1 23 24 package org.objectweb.jorm.mapper.rdb.xml2mi; 25 26 import org.objectweb.jorm.api.PException; 27 import org.objectweb.jorm.mapper.rdb.metainfo.RdbClassMultiMapping; 28 import org.objectweb.jorm.mapper.rdb.metainfo.RdbExternalTable; 29 import org.objectweb.jorm.mapper.rdb.metainfo.RdbFilter; 30 import org.objectweb.jorm.mapper.rdb.metainfo.RdbFilterParameterTypeProvider; 31 import org.objectweb.jorm.mapper.rdb.metainfo.RdbGenClassMapping; 32 import org.objectweb.jorm.mapper.rdb.metainfo.RdbJoin; 33 import org.objectweb.jorm.mapper.rdb.metainfo.RdbMapping; 34 import org.objectweb.jorm.mapper.rdb.metainfo.RdbTable; 35 import org.objectweb.jorm.metainfo.api.Class; 36 import org.objectweb.jorm.metainfo.api.GenClassRef; 37 import org.objectweb.jorm.metainfo.api.Mapping; 38 import org.objectweb.jorm.metainfo.api.MetaObject; 39 import org.objectweb.jorm.metainfo.api.NameDef; 40 import org.objectweb.jorm.metainfo.api.PrimitiveElement; 41 import org.objectweb.jorm.xml2mi.lib.BasicMappingParser; 42 import org.objectweb.medor.expression.api.Expression; 43 import org.objectweb.medor.expression.api.ExpressionException; 44 import org.objectweb.medor.expression.lib.ExpressionPrinter; 45 import org.objectweb.medor.expression.parser.string.ExpressionParser; 46 import org.objectweb.util.monolog.api.BasicLevel; 47 import org.w3c.dom.Element ; 48 import org.w3c.dom.Node ; 49 import org.w3c.dom.NodeList ; 50 51 import java.util.Iterator ; 52 53 54 58 public class RdbParser extends BasicMappingParser { 59 60 public final static String IDVALUE_SEP = "."; 62 public final static ExpressionParser expParser = new ExpressionParser(); 63 64 68 public RdbParser() { 69 } 71 72 81 private void parseClassMapping(Element classMappingElem, Mapping mapping) throws PException { 82 RdbClassMultiMapping rdbClassMapping = null; 85 rdbClassMapping = ((RdbMapping) mapping).createClassMultiMapping(""); 86 rdbClassMapping.setLogger(logger); 87 NodeList children = classMappingElem.getChildNodes(); 88 rdbClassMapping.createRdbInheritanceQuery(); 90 logger.log(BasicLevel.DEBUG, "link rdbInheritanceQuery to the rdbClassMapping"); 91 for (int i = 0; i < children.getLength(); i++) { 92 Node child = children.item(i); 93 String childName = child.getNodeName(); 94 if (logger.isLoggable(BasicLevel.DEBUG)) { 95 logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">"); 96 } 97 if (childName.equals("colocated-class")) { 98 String str = ((Element) child).getAttribute("class-name"); 99 if (logger.isLoggable(BasicLevel.DEBUG)) { 100 logger.log(BasicLevel.DEBUG, "add dependency: " + str); 101 } 102 rdbClassMapping.addDependency(str); 103 } else if (childName.equals("rdb-table-spec")) { 104 String tableName = ((Element) child).getAttribute("table-name"); 105 if (logger.isLoggable(BasicLevel.DEBUG)) 106 logger.log(BasicLevel.DEBUG, "Main table: " + tableName); 107 RdbTable table = rdbClassMapping.createRdbTable(tableName); 108 parseTableSpec((Element) child, table, currentClass); 109 } else if (childName.equals("rdb-external-table-spec")) { 110 String tableName = ((Element) child).getAttribute("table-name"); 111 if (logger.isLoggable(BasicLevel.DEBUG)) { 112 logger.log(BasicLevel.DEBUG, "External table: " + tableName); 113 } 114 RdbExternalTable table = 115 rdbClassMapping.createRdbExternalTable(tableName); 116 parseExternalTableSpec((Element) child, table, currentClass); 117 } else if (childName.equals("rdb-filter-spec")) { 118 parseFilter( 119 (Element) child, 120 rdbClassMapping.createRdbFilter(), 121 (Class )rdbClassMapping.getLinkedMO()); 122 } else if (childName.equals("id-mapping")) { 123 124 129 String linkend = ((Element) child).getAttribute("link-end"); 130 NameDef nd = getIdNameDef(rdbClassMapping, linkend); 132 if (logger.isLoggable(BasicLevel.DEBUG)) { 133 logger.log(BasicLevel.DEBUG, "link-end=< \"" + linkend + "\">"); 134 logger.log(BasicLevel.DEBUG, "nd=< " + nd + ">"); 135 } 136 rdbClassMapping.createIdentifierMapping(nd); 137 } else if ((childName.equals("rdb-class-ref-mapping")) || 138 (childName.equals("rdb-gen-class-ref-mapping"))) { 139 152 String linkend = ((Element) child).getAttribute("link-end"); 153 NameDef nd = getRefNameDef(linkend, childName); 156 String ruleName = ((Element) child).getAttribute("rule-name"); 157 rdbClassMapping.createReferenceMapping(ruleName, nd); 158 } else if (childName.equals("rdb-extension-ref-mapping")) { 159 String linkend = ((Element) child).getAttribute("link-end"); 160 NameDef nd = getNameDefFromSuper(linkend); 163 String ruleName = ((Element) child).getAttribute("rule-name"); 164 rdbClassMapping.createReferenceMapping(ruleName, nd); 165 } else if (childName.equals("parent-class-mapping")) { 166 if (logger.isLoggable(BasicLevel.DEBUG)) 167 logger.log(BasicLevel.DEBUG, "parent-class-mapping"); 168 String fqcn = ((Element) child).getAttribute("link-end"); 170 Class superClass = currentClass.getSuperClass(fqcn); 172 if (superClass == null) { 173 throw new PException("Cannot find superclass " + fqcn + 174 " for class " + currentClass.getFQName()); 175 } 176 String ruleName = ((Element) child).getAttribute("rule-name"); 177 if (logger.isLoggable(BasicLevel.DEBUG)) 178 logger.log(BasicLevel.DEBUG, "fqcn = " + fqcn + " / rule-name=" + ruleName); 179 rdbClassMapping.createParentClassMapping(ruleName, superClass); 180 } else if (childName.equals("#text")) { 181 } else if (childName.equals("#comment")) { 182 } else { 183 logger.log(BasicLevel.WARN, "element <" + childName + "> unknown !"); 184 } 185 if (logger.isLoggable(BasicLevel.DEBUG)) 186 logger.log(BasicLevel.DEBUG, "end =<" + childName + ">"); 187 } 188 } 189 190 199 private void parseGenClassMapping(Element genClassMappingElem, 200 Mapping mapping) throws PException { 201 202 214 String linkend = genClassMappingElem.getAttribute("link-end"); 215 if (getLogger().isLoggable(BasicLevel.DEBUG)) { 216 getLogger().log(BasicLevel.DEBUG, 217 "linkend of rdb-gen-class-mapping <" + linkend + ">"); 218 } 219 GenClassRef genClassRef = (GenClassRef) idvalue2genclassref.get(linkend); 220 if ((genClassRef != null) && 221 (getLogger().isLoggable(BasicLevel.DEBUG))) { 222 getLogger().log(BasicLevel.DEBUG, 223 "GenClassRef name " + genClassRef.getName()); 224 } 225 if (getLogger().isLoggable(BasicLevel.DEBUG)) { 227 getLogger().log(BasicLevel.DEBUG, 228 "create a new BasicRdbGenClassMapping for the current " + 229 "Class (" + currentClass.getName() + ")"); 230 } 231 RdbGenClassMapping rdbGenClassMapping = ((RdbMapping) mapping) 232 .createGenClassMapping("", genClassRef); 233 rdbGenClassMapping.setLogger(logger); 234 NodeList children = genClassMappingElem.getChildNodes(); 235 for (int i = 0; i < children.getLength(); i++) { 236 Node child = children.item(i); 237 String childName = child.getNodeName(); 238 if (logger.isLoggable(BasicLevel.DEBUG)) { 239 logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">"); 240 } 241 if (childName.equals("rdb-table-spec")) { 242 String tableName = ((Element) child).getAttribute("table-name"); 243 RdbTable table = rdbGenClassMapping.createRdbTable(tableName); 244 parseTableSpec((Element) child, table, genClassRef); 245 } else if (childName.equals("id-mapping")) { 246 258 String namedefName = ((Element) child).getAttribute("link-end"); 260 NameDef nd = genClassRef.getIdNameDef(namedefName); 262 if (logger.isLoggable(BasicLevel.DEBUG)) { 263 logger.log(BasicLevel.DEBUG, 264 "Fetching the ID name def of the GenClassRef " + namedefName); 265 if (nd.isFieldName()) 266 logger.log(BasicLevel.DEBUG, "fieldName: " + nd.getFieldName()); 267 else if (nd.isNameRef()) 268 logger.log(BasicLevel.DEBUG, "NameRef: " + nd.getNameRef()); 269 } 270 rdbGenClassMapping.createIdentifierMapping(nd); 272 } else if (childName.equals("rdb-external-table-spec")) { 273 String tableName = ((Element) child).getAttribute("table-name"); 274 if (logger.isLoggable(BasicLevel.DEBUG)) { 275 logger.log(BasicLevel.DEBUG, "External table: " + tableName); 276 } 277 RdbExternalTable table = 278 rdbGenClassMapping.createRdbExternalTable(tableName); 279 parseExternalTableSpec((Element) child, table, genClassRef); 280 } else if (childName.equals("rdb-ref-mapping")) { 281 298 String namedefName = ((Element) child).getAttribute("link-end"); 299 NameDef nd = null; 300 if (genClassRef.isPrimitive()) { 302 logger.log(BasicLevel.WARN, "You define a generic class of " + 303 "primitive and a useless name-def for the elements: " + 304 "generic class id=" + genClassRef.getGenClassId()); 305 continue; 306 } else if (genClassRef.isClassRef()) { 307 if (logger.isLoggable(BasicLevel.DEBUG)) { 308 logger.log(BasicLevel.DEBUG, 309 "Get the ref name def of the GenClassRef " + namedefName); 310 } 311 nd = genClassRef.getClassRef().getRefNameDef(namedefName); 312 } else if (genClassRef.isGenClassRef()) { 313 if (logger.isLoggable(BasicLevel.DEBUG)) { 314 logger.log(BasicLevel.DEBUG, 315 "Get the ref name def of the ClassRef " + namedefName); 316 } 317 nd = genClassRef.getGenClassRef().getRefNameDef(namedefName); 318 } 319 String ruleName = ((Element) child).getAttribute("rule-name"); 320 rdbGenClassMapping.createReferenceMapping(ruleName, nd); 322 } else if (childName.equals("#text")) { 323 } else { 324 logger.log(BasicLevel.WARN, "element <" + childName + "> unknown !"); 325 } 326 if (logger.isLoggable(BasicLevel.DEBUG)) { 327 logger.log(BasicLevel.DEBUG, "end =<" + childName + ">"); 328 } 329 } 330 } 331 332 private void parseTableSpec(Element tableSpecElem, 333 RdbTable table, 334 MetaObject mo) throws PException { 335 String str = tableSpecElem.getAttribute("colocated"); 336 table.setColocated(new Boolean (str).booleanValue()); 337 338 str = tableSpecElem.getAttribute("colocated-master"); 339 table.setColocatedMaster(new Boolean (str).booleanValue()); 340 341 str = tableSpecElem.getAttribute("read-only"); 342 table.setReadOnly(new Boolean (str).booleanValue()); 343 344 NodeList children = tableSpecElem.getChildNodes(); 345 for (int i = 0; i < children.getLength(); i++) { 346 Node child = children.item(i); 347 String childName = child.getNodeName(); 348 if (childName.equals("rdb-column-spec")) { 349 parseColumn(child, table, mo); 350 } 351 } 352 } 353 354 private void parseExternalTableSpec(Element tableSpecElem, 355 RdbExternalTable table, 356 MetaObject mo) throws PException { 357 String str = tableSpecElem.getAttribute("colocated"); 358 table.setColocated(new Boolean (str).booleanValue()); 359 360 str = tableSpecElem.getAttribute("colocated-master"); 361 table.setColocatedMaster(new Boolean (str).booleanValue()); 362 363 str = tableSpecElem.getAttribute("read-only"); 364 table.setReadOnly(new Boolean (str).booleanValue()); 365 366 NodeList children = tableSpecElem.getChildNodes(); 367 for (int i = 0; i < children.getLength(); i++) { 368 Node child = children.item(i); 369 String childName = child.getNodeName(); 370 if (childName.equals("rdb-column-spec")) { 371 parseColumn(child, table, mo); 372 } else if (childName.equals("rdb-join")) { 373 str = ((Element) child).getAttribute("name"); 374 parseJoin((Element) child, table.createRdbJoin(str)); 375 } 376 } 377 } 378 379 private void parseColumn(Node child, RdbTable table, MetaObject mo) 380 throws PException { 381 if (logger.isLoggable(BasicLevel.DEBUG)) { 382 logger.log(BasicLevel.DEBUG, "begin =<" + child.getNodeName() + ">"); 383 } 384 396 String linkend = ((Element) child).getAttribute("link-end"); 398 PrimitiveElement pe = null; 399 if (mo instanceof Class ) { 400 pe = getPrimitiveElement(linkend); 403 if (logger.isLoggable(BasicLevel.DEBUG)) { 404 logger.log(BasicLevel.DEBUG, "Class field name: " + linkend); 405 } 406 } else if (mo instanceof GenClassRef) { 407 pe = ((GenClassRef) mo).getHiddenField(linkend); 408 if (pe == null) { 409 pe = ((GenClassRef) mo).getPrimitiveElement(); 410 } 411 if (logger.isLoggable(BasicLevel.DEBUG)) { 412 logger.log(BasicLevel.DEBUG, "GenClass name: " + linkend); 413 } 414 } 415 String columnName = ((Element) child).getAttribute("column-name"); 416 if (logger.isLoggable(BasicLevel.DEBUG)) { 417 logger.log(BasicLevel.DEBUG, "column name: " + columnName); 418 } 419 String sqlType = ((Element) child).getAttribute("sql-type"); 420 boolean notNull = new Boolean (((Element) child). 421 getAttribute("not-null")).booleanValue(); 422 if (table instanceof RdbExternalTable) { 423 String str = ((Element) child).getAttribute("join-name"); 424 RdbJoin join = null; 425 if (str == null) { 426 Iterator it = ((RdbExternalTable) table).getRdbJoins().iterator(); 428 if (!it.hasNext()) { 429 throw new PException("No join defined in the external table "); 430 } 431 join = (RdbJoin) it.next(); 432 if (it.hasNext()) { 433 throw new PException("Several joins defined in the external" 434 + " table " + table.getName() + ", you must specify" 435 + " a join-name attribute for the column " 436 + columnName); 437 } 438 } else { 439 join = ((RdbExternalTable) table).getRdbJoin(str); 440 if (join == null) { 441 throw new PException("Impossible to define the column " 442 + columnName + " of the external table " 443 + table.getName() 444 + ": The join '" + str + "' was not defined"); 445 } 446 } 447 ((RdbExternalTable) table).createPrimitiveElementMapping( 448 pe, columnName, sqlType, notNull, join); 449 } else { 450 table.createPrimitiveElementMapping(pe, columnName, sqlType, notNull); 451 } 452 if (logger.isLoggable(BasicLevel.DEBUG)) 453 logger.log(BasicLevel.DEBUG, "end =<" + child.getNodeName() + ">"); 454 } 455 456 private void parseJoin(Element rdbJoinElem, RdbJoin rdbJoin) { 457 NodeList children = rdbJoinElem.getChildNodes(); 458 for (int i = 0; i < children.getLength(); i++) { 459 Node child = children.item(i); 460 String childName = child.getNodeName(); 461 if (logger.isLoggable(BasicLevel.DEBUG)) { 462 logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">"); 463 } 464 if (childName.equals("rdb-column-match")) { 465 String ptColumn = ((Element) child).getAttribute("column1"); 466 String etColumn = ((Element) child).getAttribute("column2"); 467 rdbJoin.addJoinColumnNames(ptColumn, etColumn); 468 } 469 if (logger.isLoggable(BasicLevel.DEBUG)) { 470 logger.log(BasicLevel.DEBUG, "end =<" + childName + ">"); 471 } 472 } 473 } 474 475 private void parseFilter( 476 Element rdbFilterElem, 477 RdbFilter rdbFilter, 478 Class theClass) 479 throws PException { 480 NodeList children = rdbFilterElem.getChildNodes(); 481 for (int i = 0; i < children.getLength(); i++) { 482 Node child = children.item(i); 483 String childName = child.getNodeName(); 484 if (logger.isLoggable(BasicLevel.DEBUG)) { 485 logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">"); 486 } 487 if (childName.equals("rdb-filter")) { 488 String filterStr = ((Element) child).getAttribute("value"); 489 rdbFilter.setStringExpression(filterStr); 490 try { 491 if (logger.isLoggable(BasicLevel.DEBUG)) { 492 logger.log(BasicLevel.DEBUG, "Parsing filter for " + filterStr); 493 } 494 Expression e = expParser.parse( 496 filterStr, 497 new RdbFilterParameterTypeProvider(theClass)); 498 if (logger.isLoggable(BasicLevel.DEBUG)) { 499 logger.log(BasicLevel.DEBUG, "Parsed filter for " + filterStr + " is: " + ExpressionPrinter.e2str(e)); 500 } 501 rdbFilter.setExpression(e); 502 } 503 catch (ExpressionException e) { 504 throw new PException(e); 505 } 506 if (logger.isLoggable(BasicLevel.DEBUG)) { 507 logger.log(BasicLevel.DEBUG, "end =<" + childName + ">"); 508 } 509 } 510 } 511 } 512 513 517 527 public void parseMapping(Element mappingElem, Mapping mapping) throws PException { 528 if (mappingElem.getNodeName().equals("rdb-class-mapping")) { 529 parseClassMapping(mappingElem, mapping); 530 } else if (mappingElem.getNodeName().equals("rdb-gen-class-mapping")) { 531 parseGenClassMapping(mappingElem, mapping); 532 } else { 533 throw new PException("Mapping element not supported by RDB: " + mappingElem.getNodeName()); 534 } 535 } 536 } 537 | Popular Tags |