1 17 package org.apache.ws.jaxme.generator.sg.impl; 18 19 import java.io.StringWriter ; 20 import java.util.ArrayList ; 21 import java.util.HashMap ; 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.Set ; 27 28 import javax.xml.XMLConstants ; 29 import javax.xml.bind.JAXBContext; 30 import javax.xml.bind.JAXBException; 31 import javax.xml.parsers.DocumentBuilder ; 32 import javax.xml.parsers.DocumentBuilderFactory ; 33 import javax.xml.parsers.ParserConfigurationException ; 34 35 import org.apache.ws.jaxme.XMLWriter; 36 import org.apache.ws.jaxme.generator.sg.ComplexContentSG; 37 import org.apache.ws.jaxme.generator.sg.ComplexTypeSG; 38 import org.apache.ws.jaxme.generator.sg.Context; 39 import org.apache.ws.jaxme.generator.sg.GroupSG; 40 import org.apache.ws.jaxme.generator.sg.ObjectSG; 41 import org.apache.ws.jaxme.generator.sg.ParticleSG; 42 import org.apache.ws.jaxme.generator.sg.SGFactory; 43 import org.apache.ws.jaxme.generator.sg.SchemaSG; 44 import org.apache.ws.jaxme.generator.sg.SchemaSGChain; 45 import org.apache.ws.jaxme.generator.sg.TypeSG; 46 import org.apache.ws.jaxme.impl.JAXBContextImpl; 47 import org.apache.ws.jaxme.impl.XMLWriterImpl; 48 import org.apache.ws.jaxme.js.JavaConstructor; 49 import org.apache.ws.jaxme.js.JavaField; 50 import org.apache.ws.jaxme.js.JavaMethod; 51 import org.apache.ws.jaxme.js.JavaQName; 52 import org.apache.ws.jaxme.js.JavaQNameImpl; 53 import org.apache.ws.jaxme.js.JavaSource; 54 import org.apache.ws.jaxme.js.JavaSourceFactory; 55 import org.apache.ws.jaxme.js.Parameter; 56 import org.apache.ws.jaxme.js.TextFile; 57 import org.apache.ws.jaxme.logging.Logger; 58 import org.apache.ws.jaxme.logging.LoggerAccess; 59 import org.apache.ws.jaxme.util.DOMSerializer; 60 import org.apache.ws.jaxme.xs.XSElement; 61 import org.apache.ws.jaxme.xs.XSGroup; 62 import org.apache.ws.jaxme.xs.XSSchema; 63 import org.apache.ws.jaxme.xs.XSType; 64 import org.apache.ws.jaxme.xs.jaxb.JAXBGlobalBindings; 65 import org.apache.ws.jaxme.xs.jaxb.JAXBJavaType; 66 import org.apache.ws.jaxme.xs.jaxb.JAXBSchema; 67 import org.apache.ws.jaxme.xs.types.XSNCName; 68 import org.apache.ws.jaxme.xs.xml.XsQName; 69 import org.w3c.dom.Document ; 70 import org.w3c.dom.Element ; 71 import org.xml.sax.Locator ; 72 import org.xml.sax.SAXException ; 73 74 75 78 public class JAXBSchemaSG implements SchemaSGChain { 79 private final static Logger log = LoggerAccess.getLogger(JAXBSchemaSG.class); 80 private final Map elementsByName = new HashMap (); 81 private final Map groupsByName = new HashMap (); 82 private final Map typesByName = new HashMap (); 83 private final SGFactory factory; 84 private final XSSchema xsSchema; 85 private final JavaSourceFactory javaSourceFactory = new JavaSourceFactory(); 86 private TypeSG[] typesByOrder; 87 private ObjectSG[] elementsByOrder; 88 private ObjectSG[] objectsByOrder; 89 private GroupSG[] groupsByOrder; 90 91 93 public JAXBSchemaSG(SGFactory pFactory, XSSchema pSchema) { 94 factory = pFactory; 95 xsSchema = pSchema; 96 javaSourceFactory.setOverwriteForced(pFactory.getGenerator().isForcingOverwrite()); 97 javaSourceFactory.setSettingReadOnly(pFactory.getGenerator().isSettingReadOnly()); 98 } 99 100 public SchemaSG getSchema(SchemaSG pController) { return pController; } 101 public Locator getLocator(SchemaSG pController) { return xsSchema.getLocator(); } 102 public SGFactory getFactory(SchemaSG pController) { return factory; } 103 protected XSSchema getXSSchema() { return xsSchema; } 104 105 public void init(SchemaSG pController) throws SAXException { 106 final String mName = "init"; 107 log.finest(mName, "->"); 108 109 Object [] childs = getXSSchema().getChilds(); 110 111 List elements = new ArrayList (); 112 List types = new ArrayList (); 113 List groups = new ArrayList (); 114 List objects = new ArrayList (); 115 for (int i = 0; i < childs.length; i++) { 116 Object o = childs[i]; 117 log.finest(mName, "Child" + o); 118 if (o instanceof XSType) { 119 TypeSG typeSG = pController.getType(((XSType) o).getName()); 120 if (typeSG == null) { 121 throw new IllegalStateException ("TypeSG not created"); 122 } 123 types.add(typeSG); 124 } else if (o instanceof XSGroup) { 125 GroupSG groupSG = pController.getGroup(((XSGroup) o).getName()); 126 if (groupSG == null) { 127 throw new IllegalStateException ("GroupSG not created"); 128 } 129 groups.add(groupSG); 130 } else if (o instanceof XSElement) { 131 ObjectSG objectSG = pController.getElement(((XSElement) o).getName()); 132 if (objectSG == null) { 133 throw new IllegalStateException ("ObjectSG not created"); 134 } 135 objects.add(objectSG); 136 elements.add(objectSG); 137 } 138 } 139 140 elementsByOrder = (ObjectSG[]) elements.toArray(new ObjectSG[elements.size()]); 141 typesByOrder = (TypeSG[]) types.toArray(new TypeSG[types.size()]); 142 groupsByOrder = (GroupSG[]) groups.toArray(new GroupSG[groups.size()]); 143 objectsByOrder = (ObjectSG[]) objects.toArray(new ObjectSG[objects.size()]); 144 log.finest(mName, "<-"); 145 } 146 147 public TypeSG getType(SchemaSG pController, XsQName pName) throws SAXException { 148 TypeSG typeSG = (TypeSG) typesByName.get(pName); 149 if (typeSG != null) { 150 return typeSG; 151 } 152 XSType type = getXSSchema().getType(pName); 153 if (type == null) { 154 return null; 155 } 156 typeSG = pController.getFactory().getTypeSG(type); 157 typesByName.put(pName, typeSG); 158 return typeSG; 159 } 160 161 public GroupSG[] getGroups(SchemaSG pController) throws SAXException { 162 return groupsByOrder; 163 } 164 165 public GroupSG getGroup(SchemaSG pController, XsQName pName) throws SAXException { 166 GroupSG groupSG = (GroupSG) groupsByName.get(pName); 167 if (groupSG != null) { 168 return groupSG; 169 } 170 XSGroup group = getXSSchema().getGroup(pName); 171 if (group == null) { 172 return null; 173 } 174 groupSG = pController.getFactory().getGroupSG(group); 175 groupsByName.put(pName, groupSG); 176 return groupSG; 177 } 178 179 public TypeSG[] getTypes(SchemaSG pController) throws SAXException { 180 return typesByOrder; 181 } 182 183 public ObjectSG[] getObjects(SchemaSG pController) throws SAXException { 184 return objectsByOrder; 185 } 186 187 public ObjectSG getElement(SchemaSG pController, XsQName pName) throws SAXException { 188 ObjectSG objectSG = (ObjectSG) elementsByName.get(pName); 189 if (objectSG != null) { 190 return objectSG; 191 } 192 XSElement element = getXSSchema().getElement(pName); 193 if (element == null) { 194 return null; 195 } 196 objectSG = pController.getFactory().getObjectSG(element); 197 elementsByName.put(pName, objectSG); 198 return objectSG; 199 } 200 201 public String getCollectionType(SchemaSG pController) { 202 XSSchema schema = getXSSchema(); 203 if (schema instanceof JAXBSchema) { 204 JAXBSchema jaxbSchema = (JAXBSchema) schema; 205 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 206 if (globalBindings != null) { 207 String result = globalBindings.getCollectionType(); 208 if (result != null) { 209 return result; 210 } 211 } 212 } 213 return ArrayList .class.getName(); 214 } 215 216 public JavaSourceFactory getJavaSourceFactory(SchemaSG pController) { 217 return javaSourceFactory; 218 } 219 220 public void generate(SchemaSG pController) throws SAXException { 221 TypeSG[] types = pController.getTypes(); 222 for (int i = 0; i < types.length; i++) { 223 types[i].generate(); 224 } 225 226 ObjectSG[] objects = pController.getObjects(); 227 for (int i = 0; i < objects.length; i++) { 228 objects[i].generate(); 229 } 230 231 pController.generateJaxbProperties(); 232 } 233 234 public ObjectSG[] getElements(SchemaSG pController) throws SAXException { 235 return elementsByOrder; 236 } 237 238 public boolean isBindingStyleModelGroup(SchemaSG pController) { 239 XSSchema schema = getXSSchema(); 240 if (schema instanceof JAXBSchema) { 241 JAXBSchema jaxbSchema = (JAXBSchema) schema; 242 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 243 if (globalBindings != null) { 244 return globalBindings.isBindingStyleModelGroup(); 245 } 246 } 247 return false; 248 } 249 250 public boolean isChoiceContentProperty(SchemaSG pController) { 251 XSSchema schema = getXSSchema(); 252 if (schema instanceof JAXBSchema) { 253 JAXBSchema jaxbSchema = (JAXBSchema) schema; 254 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 255 if (globalBindings != null) { 256 return globalBindings.isChoiceContentProperty(); 257 } 258 } 259 return false; 260 } 261 262 public boolean isFailFastCheckEnabled(SchemaSG pController) { 263 XSSchema schema = getXSSchema(); 264 if (schema instanceof JAXBSchema) { 265 JAXBSchema jaxbSchema = (JAXBSchema) schema; 266 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 267 if (globalBindings != null) { 268 return globalBindings.isEnableFailFastCheck(); 269 } 270 } 271 return false; 272 } 273 274 public boolean isJavaNamingConventionsEnabled(SchemaSG pController) { 275 XSSchema schema = getXSSchema(); 276 if (schema instanceof JAXBSchema) { 277 JAXBSchema jaxbSchema = (JAXBSchema) schema; 278 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 279 if (globalBindings != null) { 280 return globalBindings.isEnableJavaNamingConventions(); 281 } 282 } 283 return true; 284 } 285 286 public boolean isFixedAttributeConstantProperty(SchemaSG pController) { 287 XSSchema schema = getXSSchema(); 288 if (schema instanceof JAXBSchema) { 289 JAXBSchema jaxbSchema = (JAXBSchema) schema; 290 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 291 if (globalBindings != null) { 292 return globalBindings.isFixedAttributeAsConstantProperty(); 293 } 294 } 295 return false; 296 } 297 298 public boolean isGeneratingIsSetMethod(SchemaSG pController) { 299 XSSchema schema = getXSSchema(); 300 if (schema instanceof JAXBSchema) { 301 JAXBSchema jaxbSchema = (JAXBSchema) schema; 302 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 303 if (globalBindings != null) { 304 return globalBindings.isGenerateIsSetMethod(); 305 } 306 } 307 return false; 308 } 309 310 public boolean isUnderscoreWordSeparator(SchemaSG pController) { 311 XSSchema schema = getXSSchema(); 312 if (schema instanceof JAXBSchema) { 313 JAXBSchema jaxbSchema = (JAXBSchema) schema; 314 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 315 if (globalBindings != null) { 316 return JAXBGlobalBindings.UnderscoreBinding.AS_WORD_SEPARATOR.equals(globalBindings.getUnderscoreBinding()); 317 } 318 } 319 return true; 320 } 321 322 public JAXBJavaType[] getJAXBJavaTypes(SchemaSG pController) { 323 XSSchema schema = getXSSchema(); 324 if (schema instanceof JAXBSchema) { 325 JAXBSchema jaxbSchema = (JAXBSchema) schema; 326 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 327 if (globalBindings != null) { 328 return globalBindings.getJavaType(); 329 } 330 } 331 return new JAXBJavaType[0]; 332 } 333 334 public XsQName[] getTypesafeEnumBase(SchemaSG pController) { 335 XSSchema schema = getXSSchema(); 336 if (schema instanceof JAXBSchema) { 337 JAXBSchema jaxbSchema = (JAXBSchema) schema; 338 JAXBGlobalBindings globalBindings = jaxbSchema.getJAXBGlobalBindings(); 339 if (globalBindings != null) { 340 return globalBindings.getTypesafeEnumBase(); 341 } 342 } 343 return new XsQName[]{XSNCName.getInstance().getName()}; 344 } 345 346 public Document getConfigFile(SchemaSG pController, String pPackageName, List pContextList) 347 throws SAXException { 348 final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 349 dbf.setNamespaceAware(true); 350 dbf.setValidating(false); 351 final DocumentBuilder db; 352 try { 353 db = dbf.newDocumentBuilder(); 354 } catch (ParserConfigurationException e) { 355 throw new SAXException ("Failed to create a DocumentBuilder: " + e.getMessage(), e); 356 } 357 final Document doc = db.newDocument(); 358 final String uri = JAXBContextImpl.CONFIGURATION_URI; 359 final Element root = doc.createElementNS(uri, "Configuration"); 360 root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", uri); 361 doc.appendChild(root); 362 363 for (Iterator iter = pContextList.iterator(); iter.hasNext(); ) { 364 Object o = iter.next(); 365 Context ctx, typeCtx; 366 if (o instanceof ObjectSG) { 367 ObjectSG oSG = (ObjectSG) o; 368 ctx = oSG.getClassContext(); 369 typeCtx = oSG.getTypeSG().getComplexTypeSG().getClassContext(); 370 } else { 371 TypeSG tSG = (TypeSG) o; 372 ctx = typeCtx = tSG.getComplexTypeSG().getClassContext(); 373 } 374 375 String packageName = ctx.getXMLInterfaceName().getPackageName(); 376 if (packageName == null) { 377 packageName = ""; 378 } 379 if (!packageName.equals(pPackageName)) { 380 continue; 381 } 382 383 Element manager = doc.createElementNS(uri, "Manager"); 384 root.appendChild(manager); 385 manager.setAttributeNS(null, "elementInterface", ctx.getXMLInterfaceName().toString()); 386 manager.setAttributeNS(null, "elementClass", ctx.getXMLImplementationName().toString()); 387 manager.setAttributeNS(null, "handlerClass", typeCtx.getXMLHandlerName().toString()); 388 manager.setAttributeNS(null, "driverClass", typeCtx.getXMLSerializerName().toString()); 389 manager.setAttributeNS(null, "validatorClass", ctx.getXMLValidatorName().toString()); 390 if (o instanceof ObjectSG) { 391 XsQName name = ((ObjectSG) o).getName(); 392 manager.setAttributeNS(null, "qName", name.toString()); 393 if (name.getPrefix() != null) { 394 manager.setAttributeNS(null, "prefix", name.getPrefix()); 395 } 396 } 397 } 398 return doc; 399 } 400 401 protected String generateConfigFile(SchemaSG pController, String pPackageName, List pContextList) throws SAXException { 402 Document doc = pController.getConfigFile(pPackageName, pContextList); 403 StringWriter sw = new StringWriter (); 404 XMLWriter xw = new XMLWriterImpl(); 405 try { 406 xw.setWriter(sw); 407 } catch (JAXBException e) { 408 throw new SAXException (e); 409 } 410 DOMSerializer ds = new DOMSerializer(); 411 ds.serialize(doc, xw); 412 return sw.toString(); 413 } 414 415 public void generateJaxbProperties(SchemaSG pController) throws SAXException { 416 List contextList = new ArrayList (); 417 ObjectSG[] elements = pController.getElements(); 418 for (int i = 0; i < elements.length; i++) { 419 if (elements[i].getTypeSG().isComplex()) { 420 contextList.add(elements[i]); 421 } 422 } 423 TypeSG[] types = pController.getTypes(); 424 for (int i = 0; i < types.length; i++) { 425 if (types[i].isComplex()) { 426 contextList.add(types[i]); 427 } 428 } 429 430 431 Set packages = new HashSet (); 432 for (Iterator iter = contextList.iterator(); iter.hasNext(); ) { 433 Object o = iter.next(); 434 Context ctx; 435 if (o instanceof ObjectSG) { 436 ctx = ((ObjectSG) o).getClassContext(); 437 } else { 438 ctx = ((TypeSG) o).getComplexTypeSG().getClassContext(); 439 } 440 String packageName = ctx.getXMLInterfaceName().getPackageName(); 441 if (packages.contains(packageName)) { 442 continue; 443 } 444 445 TextFile textFile = pController.getJavaSourceFactory().newTextFile(packageName, "jaxb.properties"); 446 textFile.addLine(JAXBContext.JAXB_CONTEXT_FACTORY + "=" + JAXBContextImpl.class.getName()); 447 packages.add(packageName); 448 449 String configFile = generateConfigFile(pController, packageName, contextList); 450 TextFile confFile = pController.getJavaSourceFactory().newTextFile(packageName, "Configuration.xml"); 451 confFile.setContents(configFile); 452 453 getObjectFactory(pController, packageName, contextList); 454 } 455 } 456 457 protected JavaSource getObjectFactory(SchemaSG pController, String pPackageName, 458 List pContextList) 459 throws SAXException { 460 JavaQName qName = JavaQNameImpl.getInstance(pPackageName, "ObjectFactory"); 461 JavaSource js = pController.getJavaSourceFactory().newJavaSource(qName, "public"); 462 JavaField jf = js.newJavaField("jaxbContext", JAXBContextImpl.class, "private"); 463 JavaField properties = js.newJavaField("properties", Map .class, "private"); 464 465 JavaConstructor jcon = js.newJavaConstructor("public"); 466 jcon.addThrows(JAXBException.class); 467 jcon.addLine(jf, " = (", JAXBContextImpl.class, ") ", 468 JAXBContext.class, ".newInstance(", 469 JavaSource.getQuoted(pPackageName), ");"); 470 471 JavaMethod newInstanceMethod = js.newJavaMethod("newInstance", Object .class, "public"); 472 newInstanceMethod.addThrows(JAXBException.class); 473 Parameter pElementInterface = newInstanceMethod.addParam(Class .class, "pElementInterface"); 474 newInstanceMethod.addLine("return ", jf, ".getManager(", pElementInterface, ").getElementJ();"); 475 476 { 477 JavaMethod getPropertyMethod = js.newJavaMethod("getProperty", Object .class, "public"); 478 Parameter pName = getPropertyMethod.addParam(String .class, "pName"); 479 getPropertyMethod.addIf(properties, " == null"); 480 getPropertyMethod.addLine("return null;"); 481 getPropertyMethod.addEndIf(); 482 getPropertyMethod.addLine("return ", properties, ".get(", pName, ");"); 483 } 484 485 { 486 JavaMethod setPropertyMethod = js.newJavaMethod("setProperty", void.class, "public"); 487 Parameter pName = setPropertyMethod.addParam(String .class, "pName"); 488 Parameter pValue = setPropertyMethod.addParam(Object .class, "pValue"); 489 setPropertyMethod.addIf(properties, " == null"); 490 setPropertyMethod.addLine(properties, " = new ", HashMap .class, "();"); 491 setPropertyMethod.addEndIf(); 492 setPropertyMethod.addLine(properties, ".put(", pName, ", ", pValue, ");"); 493 } 494 495 Set contextSet = new HashSet (); 496 for (Iterator iter = pContextList.iterator(); iter.hasNext(); ) { 497 Object o = iter.next(); 498 TypeSG typeSG; 499 if (o instanceof ObjectSG) { 500 ObjectSG objectSG = ((ObjectSG) o); 501 typeSG = objectSG.getTypeSG(); 502 generateCreateMethod(js, null, objectSG.getClassContext()); 503 } else if (o instanceof TypeSG) { 505 typeSG = (TypeSG) o; 506 } else { 507 continue; 508 } 509 510 generateCreateMethod(js, contextSet, typeSG, null); 511 } 512 513 return js; 514 } 515 516 private void generateCreateMethod(JavaSource pJs, Set pContextSet, 517 TypeSG pType, String pPrefix) throws SAXException { 518 if (!pType.isComplex() || pContextSet.contains(pType)) { 519 return; 520 } 521 String prefix = generateCreateMethod(pJs, pPrefix, pType.getComplexTypeSG().getClassContext()); 523 pContextSet.add(pType); 524 generateCreateMethods(pJs, pType, prefix, pContextSet); 525 } 526 527 529 private void generateCreateMethods(JavaSource pJs, ParticleSG pParticle, 530 String pName, Set pContextSet) 531 throws SAXException { 532 if (pParticle.isGroup()) { 533 GroupSG group = pParticle.getGroupSG(); 534 generateCreateMethods(pJs, group.getParticles(), pName, pContextSet); 535 } else if (pParticle.isElement()) { 536 ObjectSG oSG = pParticle.getObjectSG(); 537 if (oSG.isGlobal()) { 538 return; } 540 TypeSG tSG = oSG.getTypeSG(); 541 if (tSG.isGlobalType()) { 542 return; } 544 generateCreateMethod(pJs, pContextSet, tSG, pName); 545 } else if (pParticle.isWildcard()) { 546 throw new IllegalStateException ("TODO: Add support for wildcards here."); 547 } else { 548 throw new IllegalStateException ("Invalid class type"); 549 } 550 } 551 552 554 private void generateCreateMethods(JavaSource pJs, ParticleSG[] pParticles, 555 String pName, Set pContextSet) 556 throws SAXException { 557 for (int i = 0; i < pParticles.length; i++) { 558 generateCreateMethods(pJs, pParticles[i], pName, pContextSet); 559 } 560 } 561 562 564 private void generateCreateMethods(JavaSource pJs, TypeSG pType, 565 String pName, Set pContextSet) 566 throws SAXException { 567 ComplexTypeSG ctSG = pType.getComplexTypeSG(); 568 if (ctSG.hasSimpleContent()) { 569 return; } 571 ComplexContentSG ccSG = ctSG.getComplexContentSG(); 572 if (ccSG.isEmpty()) { 573 return; 574 } 575 ParticleSG particle = ccSG.getRootParticle(); 576 generateCreateMethods(pJs, particle, pName, pContextSet); 577 } 578 579 584 private String generateCreateMethod(JavaSource pSource, String pPrefix, 585 Context pContext) { 586 JavaQName resultName = pContext.getXMLInterfaceName(); 587 String className = resultName.isInnerClass() ? resultName.getInnerClassName() : resultName.getClassName(); 588 String result = Character.toUpperCase(className.charAt(0)) + className.substring(1); 589 boolean anonymous = pPrefix != null; 590 if (anonymous) { 591 result = pPrefix + result; 592 } 593 String methodName = "create" + result; 594 JavaMethod createMethod = pSource.newJavaMethod(methodName, resultName, "public"); 595 createMethod.addThrows(JAXBException.class); 596 if (anonymous) { 597 createMethod.addLine("return new ", pContext.getXMLImplementationName(), "();"); 598 } else { 599 createMethod.addLine("return (", resultName, ") newInstance(", resultName, ".class);"); 600 } 601 return result; 602 } 603 } 604 | Popular Tags |