0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one
0003: * or more contributor license agreements. See the NOTICE file
0004: * distributed with this work for additional information
0005: * regarding copyright ownership. The ASF licenses this file
0006: * to you under the Apache License, Version 2.0 (the
0007: * "License"); you may not use this file except in compliance
0008: * with the License. You may obtain a copy of the License at
0009: *
0010: * http://www.apache.org/licenses/LICENSE-2.0
0011: *
0012: * Unless required by applicable law or agreed to in writing,
0013: * software distributed under the License is distributed on an
0014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015: * KIND, either express or implied. See the License for the
0016: * specific language governing permissions and limitations
0017: * under the License.
0018: */
0019: package org.apache.axis2.schema.writer;
0020:
0021: import org.apache.axis2.schema.*;
0022: import org.apache.axis2.schema.i18n.SchemaCompilerMessages;
0023: import org.apache.axis2.schema.typemap.JavaTypeMap;
0024: import org.apache.axis2.schema.util.PrimitiveTypeFinder;
0025: import org.apache.axis2.schema.util.SchemaPropertyLoader;
0026: import org.apache.axis2.schema.util.PrimitiveTypeWrapper;
0027: import org.apache.axis2.util.*;
0028: import org.apache.commons.logging.Log;
0029: import org.apache.commons.logging.LogFactory;
0030: import org.apache.ws.commons.schema.XmlSchemaElement;
0031: import org.apache.ws.commons.schema.XmlSchemaSimpleType;
0032: import org.apache.axiom.om.OMElement;
0033: import org.apache.axiom.om.OMAttribute;
0034: import org.w3c.dom.Document;
0035: import org.w3c.dom.Element;
0036:
0037: import javax.xml.namespace.QName;
0038: import javax.xml.parsers.ParserConfigurationException;
0039: import javax.xml.transform.Templates;
0040: import javax.xml.transform.TransformerConfigurationException;
0041: import javax.xml.transform.TransformerFactory;
0042: import javax.xml.transform.Transformer;
0043: import javax.xml.transform.stream.StreamSource;
0044: import java.io.*;
0045: import java.util.*;
0046:
0047: import com.ibm.wsdl.util.xml.DOM2Writer;
0048:
0049: /**
0050: * Java Bean writer for the schema compiler.
0051: */
0052: public class JavaBeanWriter implements BeanWriter {
0053:
0054: private static final Log log = LogFactory
0055: .getLog(JavaBeanWriter.class);
0056:
0057: public static final String WRAPPED_DATABINDING_CLASS_NAME = "WrappedDatabinder";
0058:
0059: private String javaBeanTemplateName = null;
0060:
0061: private boolean templateLoaded = false;
0062:
0063: private Templates templateCache;
0064:
0065: private List namesList;
0066:
0067: private static int count = 0;
0068:
0069: private boolean wrapClasses = false;
0070:
0071: private boolean writeClasses = false;
0072:
0073: private String packageName = null;
0074:
0075: private File rootDir;
0076:
0077: private Document globalWrappedDocument;
0078:
0079: private Map modelMap = new HashMap();
0080:
0081: private static final String DEFAULT_PACKAGE = "adb";
0082:
0083: private Map baseTypeMap = new JavaTypeMap().getTypeMap();
0084:
0085: private Map ns2packageNameMap = new HashMap();
0086:
0087: private boolean isHelperMode = false;
0088:
0089: private boolean isSuppressPrefixesMode = false;
0090:
0091: /**
0092: * package for the mapping class
0093: */
0094: private String mappingClassPackage = null;
0095:
0096: public static final String EXTENSION_MAPPER_CLASSNAME = "ExtensionMapper";
0097: // a list of externally identified QNames to be processed. This becomes
0098: // useful when only a list of external elements need to be processed
0099:
0100: public static final String DEFAULT_CLASS_NAME = OMElement.class
0101: .getName();
0102: public static final String DEFAULT_CLASS_ARRAY_NAME = "org.apache.axiom.om.OMElement[]";
0103:
0104: public static final String DEFAULT_ATTRIB_CLASS_NAME = OMAttribute.class
0105: .getName();
0106: public static final String DEFAULT_ATTRIB_ARRAY_CLASS_NAME = "org.apache.axiom.om.OMAttribute[]";
0107:
0108: /**
0109: * Default constructor
0110: */
0111: public JavaBeanWriter() {
0112: }
0113:
0114: /**
0115: * This returns a map of Qnames vs DOMDocument models. One can use this
0116: * method to obtain the raw DOMmodels used to write the classes. This has no
0117: * meaning when the classes are supposed to be wrapped so the
0118: *
0119: * @return Returns Map.
0120: * @see BeanWriter#getModelMap()
0121: */
0122: public Map getModelMap() {
0123: return modelMap;
0124: }
0125:
0126: public String getDefaultClassName() {
0127: return DEFAULT_CLASS_NAME;
0128: }
0129:
0130: public String getDefaultClassArrayName() {
0131: return DEFAULT_CLASS_ARRAY_NAME;
0132: }
0133:
0134: public String getDefaultAttribClassName() {
0135: return DEFAULT_ATTRIB_CLASS_NAME;
0136: }
0137:
0138: public String getDefaultAttribArrayClassName() {
0139: return DEFAULT_ATTRIB_ARRAY_CLASS_NAME;
0140: }
0141:
0142: public void init(CompilerOptions options)
0143: throws SchemaCompilationException {
0144: try {
0145:
0146: // set all state variables to default values
0147: modelMap = new HashMap();
0148: ns2packageNameMap = new HashMap();
0149: mappingClassPackage = null;
0150:
0151: initWithFile(options.getOutputLocation());
0152: packageName = options.getPackageName();
0153: writeClasses = options.isWriteOutput();
0154: if (!writeClasses) {
0155: wrapClasses = false;
0156: } else {
0157: wrapClasses = options.isWrapClasses();
0158: }
0159:
0160: // if the wrap mode is set then create a global document to keep the
0161: // wrapped
0162: // element models
0163: if (options.isWrapClasses()) {
0164: globalWrappedDocument = XSLTUtils.getDocument();
0165: Element rootElement = XSLTUtils.getElement(
0166: globalWrappedDocument, "beans");
0167: globalWrappedDocument.appendChild(rootElement);
0168: XSLTUtils.addAttribute(globalWrappedDocument, "name",
0169: WRAPPED_DATABINDING_CLASS_NAME, rootElement);
0170: String tempPackageName;
0171:
0172: if (packageName != null && packageName.endsWith(".")) {
0173: tempPackageName = this .packageName.substring(0,
0174: this .packageName.lastIndexOf("."));
0175: } else {
0176: tempPackageName = DEFAULT_PACKAGE;
0177: }
0178:
0179: XSLTUtils.addAttribute(globalWrappedDocument,
0180: "package", tempPackageName, rootElement);
0181: }
0182:
0183: // add the ns mappings
0184: this .ns2packageNameMap = options.getNs2PackageMap();
0185: //set helper mode
0186: this .isHelperMode = options.isHelperMode();
0187: // set suppress prefixes mode
0188: this .isSuppressPrefixesMode = options
0189: .isSuppressPrefixesMode();
0190:
0191: //set mapper class package if present
0192: if (options.isMapperClassPackagePresent()) {
0193: this .mappingClassPackage = options
0194: .getMapperClassPackage();
0195: }
0196:
0197: } catch (IOException e) {
0198: throw new SchemaCompilationException(e);
0199: } catch (ParserConfigurationException e) {
0200: throw new SchemaCompilationException(e); // todo need to put
0201: // correct error
0202: // messages
0203: }
0204: }
0205:
0206: /**
0207: * @param element
0208: * @param typeMap
0209: * @param metainf
0210: * @return Returns String.
0211: * @throws SchemaCompilationException
0212: */
0213: public String write(XmlSchemaElement element, Map typeMap,
0214: BeanWriterMetaInfoHolder metainf)
0215: throws SchemaCompilationException {
0216:
0217: try {
0218: QName qName = element.getQName();
0219:
0220: return process(qName, metainf, typeMap, true, false);
0221: } catch (Exception e) {
0222: e.printStackTrace();
0223: throw new SchemaCompilationException(e);
0224: }
0225:
0226: }
0227:
0228: /**
0229: * `
0230: * @param qName
0231: * @param typeMap
0232: * @param metainf
0233: * @param isAbstract
0234: * @return
0235: * @throws SchemaCompilationException
0236: */
0237: public String write(QName qName, Map typeMap,
0238: BeanWriterMetaInfoHolder metainf, boolean isAbstract)
0239: throws SchemaCompilationException {
0240:
0241: try {
0242: // determine the package for this type.
0243: return process(qName, metainf, typeMap, false, isAbstract);
0244:
0245: } catch (SchemaCompilationException e) {
0246: throw e;
0247: } catch (Exception e) {
0248: throw new SchemaCompilationException(e);
0249: }
0250:
0251: }
0252:
0253: /**
0254: * @throws Exception
0255: * @see BeanWriter#writeBatch()
0256: */
0257: public void writeBatch() throws SchemaCompilationException {
0258: try {
0259: if (wrapClasses) {
0260: String tempPackage;
0261: if (packageName == null) {
0262: tempPackage = DEFAULT_PACKAGE;
0263: } else {
0264: tempPackage = packageName;
0265: }
0266: File out = createOutFile(tempPackage,
0267: WRAPPED_DATABINDING_CLASS_NAME);
0268: // parse with the template and create the files
0269:
0270: parse(globalWrappedDocument, out);
0271: }
0272: } catch (Exception e) {
0273: throw new SchemaCompilationException(e);
0274: }
0275: }
0276:
0277: /**
0278: * @param simpleType
0279: * @param typeMap
0280: * @param metainf
0281: * @return Returns String.
0282: * @throws SchemaCompilationException
0283: * @see BeanWriter#write(org.apache.ws.commons.schema.XmlSchemaSimpleType,
0284: * java.util.Map, org.apache.axis2.schema.BeanWriterMetaInfoHolder)
0285: */
0286: public String write(XmlSchemaSimpleType simpleType, Map typeMap,
0287: BeanWriterMetaInfoHolder metainf)
0288: throws SchemaCompilationException {
0289: try {
0290: QName qName = simpleType.getQName();
0291: if (qName == null) {
0292: qName = (QName) simpleType
0293: .getMetaInfoMap()
0294: .get(
0295: SchemaConstants.SchemaCompilerInfoHolder.FAKE_QNAME);
0296: }
0297: metainf.addtStatus(qName,
0298: SchemaConstants.SIMPLE_TYPE_OR_CONTENT);
0299: return process(qName, metainf, typeMap, true, false);
0300: } catch (Exception e) {
0301: throw new SchemaCompilationException(e);
0302: }
0303: }
0304:
0305: /**
0306: * @param rootDir
0307: * @throws IOException
0308: * @see BeanWriter#init(java.io.File)
0309: */
0310: private void initWithFile(File rootDir) throws IOException {
0311: if (rootDir == null) {
0312: this .rootDir = new File(".");
0313: } else if (!rootDir.isDirectory()) {
0314: throw new IOException(SchemaCompilerMessages
0315: .getMessage("schema.rootnotfolderexception"));
0316: } else {
0317: this .rootDir = rootDir;
0318: }
0319:
0320: namesList = new ArrayList();
0321: javaBeanTemplateName = SchemaPropertyLoader.getBeanTemplate();
0322: }
0323:
0324: /**
0325: * Make the fully qualified class name for an element or named type
0326: *
0327: * @param qName the qualified Name for this element or type in the schema
0328: * @return the appropriate fully qualified class name to use in generated
0329: * code
0330: */
0331: public String makeFullyQualifiedClassName(QName qName) {
0332:
0333: String namespaceURI = qName.getNamespaceURI();
0334: String basePackageName;
0335:
0336: String packageName = getPackage(namespaceURI);
0337:
0338: String originalName = qName.getLocalPart();
0339: String className = makeUniqueJavaClassName(this .namesList,
0340: originalName);
0341:
0342: String packagePrefix = null;
0343:
0344: String fullyqualifiedClassName;
0345:
0346: if (wrapClasses)
0347: packagePrefix = (this .packageName == null ? DEFAULT_PACKAGE
0348: + "." : this .packageName)
0349: + WRAPPED_DATABINDING_CLASS_NAME;
0350: else if (writeClasses)
0351: packagePrefix = packageName;
0352: if (packagePrefix != null)
0353: fullyqualifiedClassName = packagePrefix
0354: + (packagePrefix.endsWith(".") ? "" : ".")
0355: + className;
0356: else
0357: fullyqualifiedClassName = className;
0358: // return the fully qualified class name
0359: return fullyqualifiedClassName;
0360: }
0361:
0362: private String getPackage(String namespaceURI) {
0363: String basePackageName;
0364: if ((ns2packageNameMap != null)
0365: && ns2packageNameMap.containsKey(namespaceURI)) {
0366: basePackageName = (String) ns2packageNameMap
0367: .get(namespaceURI);
0368: } else {
0369: basePackageName = URLProcessor
0370: .makePackageName(namespaceURI);
0371: }
0372:
0373: return this .packageName == null ? basePackageName
0374: : this .packageName + basePackageName;
0375: }
0376:
0377: /**
0378: * A util method that holds common code for the complete schema that the
0379: * generated XML complies to look under other/beanGenerationSchema.xsd
0380: *
0381: * @param qName
0382: * @param metainf
0383: * @param typeMap
0384: * @param isElement
0385: * @param fullyQualifiedClassName the name returned by makeFullyQualifiedClassName() or null if
0386: * it wasn't called
0387: * @return Returns String.
0388: * @throws Exception
0389: */
0390: private String process(QName qName,
0391: BeanWriterMetaInfoHolder metainf, Map typeMap,
0392: boolean isElement, boolean isAbstract) throws Exception {
0393: String fullyQualifiedClassName = metainf.getOwnClassName();
0394: if (fullyQualifiedClassName == null)
0395: fullyQualifiedClassName = makeFullyQualifiedClassName(qName);
0396: String className = fullyQualifiedClassName
0397: .substring(1 + fullyQualifiedClassName.lastIndexOf('.'));
0398: String basePackageName;
0399: if (fullyQualifiedClassName.lastIndexOf('.') == -1) {// no 'dots' so
0400: // the package
0401: // is not there
0402: basePackageName = "";
0403: } else {
0404: basePackageName = fullyQualifiedClassName.substring(0,
0405: fullyQualifiedClassName.lastIndexOf('.'));
0406: }
0407:
0408: String originalName = qName == null ? "" : qName.getLocalPart();
0409: ArrayList propertyNames = new ArrayList();
0410:
0411: if (!templateLoaded) {
0412: loadTemplate();
0413: }
0414:
0415: // if wrapped then do not write the classes now but add the models to a
0416: // global document. However in order to write the
0417: // global class that is generated, one needs to call the writeBatch()
0418: // method
0419: if (wrapClasses) {
0420: globalWrappedDocument.getDocumentElement().appendChild(
0421: getBeanElement(globalWrappedDocument, className,
0422: originalName, basePackageName, qName,
0423: isElement, isAbstract, metainf,
0424: propertyNames, typeMap));
0425:
0426: } else {
0427: // create the model
0428: Document model = XSLTUtils.getDocument();
0429: // make the XML
0430: model.appendChild(getBeanElement(model, className,
0431: originalName, basePackageName, qName, isElement,
0432: isAbstract, metainf, propertyNames, typeMap));
0433:
0434: if (writeClasses) {
0435: // create the file
0436: File out = createOutFile(basePackageName, className);
0437: // parse with the template and create the files
0438:
0439: if (isHelperMode) {
0440:
0441: XSLTUtils.addAttribute(model, "helperMode", "yes",
0442: model.getDocumentElement());
0443:
0444: // Generate bean classes
0445: parse(model, out);
0446:
0447: // Generating the helper classes
0448: out = createOutFile(basePackageName, className
0449: + "Helper");
0450: XSLTUtils.addAttribute(model, "helper", "yes",
0451: model.getDocumentElement());
0452: parse(model, out);
0453:
0454: } else {
0455: //No helper mode - just generate the classes
0456: parse(model, out);
0457: }
0458: }
0459:
0460: // add the model to the model map
0461: modelMap.put(new QName(qName.getNamespaceURI(), className),
0462: model);
0463:
0464: }
0465:
0466: // return the fully qualified class name
0467: return fullyQualifiedClassName;
0468:
0469: }
0470:
0471: /**
0472: * @param model
0473: * @param className
0474: * @param originalName
0475: * @param packageName
0476: * @param qName
0477: * @param isElement
0478: * @param metainf
0479: * @param propertyNames
0480: * @param typeMap
0481: * @return Returns Element.
0482: * @throws SchemaCompilationException
0483: */
0484: private Element getBeanElement(Document model, String className,
0485: String originalName, String packageName, QName qName,
0486: boolean isElement, boolean isAbstract,
0487: BeanWriterMetaInfoHolder metainf, ArrayList propertyNames,
0488: Map typeMap) throws SchemaCompilationException {
0489:
0490: Element rootElt = XSLTUtils.getElement(model, "bean");
0491: XSLTUtils.addAttribute(model, "name", className, rootElt);
0492: XSLTUtils.addAttribute(model, "originalName", originalName,
0493: rootElt);
0494: XSLTUtils.addAttribute(model, "package", packageName, rootElt);
0495: XSLTUtils.addAttribute(model, "nsuri", qName.getNamespaceURI(),
0496: rootElt);
0497: XSLTUtils
0498: .addAttribute(model, "nsprefix",
0499: isSuppressPrefixesMode ? "" : getPrefixForURI(
0500: qName.getNamespaceURI(), qName
0501: .getPrefix()), rootElt);
0502:
0503: if (!wrapClasses) {
0504: XSLTUtils.addAttribute(model, "unwrapped", "yes", rootElt);
0505: }
0506:
0507: if (isAbstract) {
0508: XSLTUtils.addAttribute(model, "isAbstract", "yes", rootElt);
0509: }
0510:
0511: if (!writeClasses) {
0512: XSLTUtils.addAttribute(model, "skip-write", "yes", rootElt);
0513: }
0514:
0515: if (!isElement) {
0516: XSLTUtils.addAttribute(model, "type", "yes", rootElt);
0517: }
0518:
0519: if (metainf.isAnonymous()) {
0520: XSLTUtils.addAttribute(model, "anon", "yes", rootElt);
0521: }
0522:
0523: if (metainf.isExtension()) {
0524: XSLTUtils.addAttribute(model, "extension", metainf
0525: .getExtensionClassName(), rootElt);
0526:
0527: }
0528: if (metainf.isRestriction()) {
0529: XSLTUtils.addAttribute(model, "restriction", metainf
0530: .getRestrictionClassName(), rootElt);
0531:
0532: }
0533: //add the mapper class name
0534: XSLTUtils.addAttribute(model, "mapperClass",
0535: getFullyQualifiedMapperClassName(), rootElt);
0536:
0537: if (metainf.isChoice()) {
0538: XSLTUtils.addAttribute(model, "choice", "yes", rootElt);
0539: }
0540:
0541: if (metainf.isSimple()) {
0542: XSLTUtils.addAttribute(model, "simple", "yes", rootElt);
0543: }
0544:
0545: if (metainf.isUnion()) {
0546: XSLTUtils.addAttribute(model, "union", "yes", rootElt);
0547: }
0548:
0549: if (metainf.isList()) {
0550: XSLTUtils.addAttribute(model, "list", "yes", rootElt);
0551: }
0552:
0553: if (metainf.isOrdered()) {
0554: XSLTUtils.addAttribute(model, "ordered", "yes", rootElt);
0555: }
0556:
0557: if (isElement && metainf.isNillable(qName)) {
0558: XSLTUtils.addAttribute(model, "nillable", "yes", rootElt);
0559: }
0560:
0561: if (metainf.isParticleClass()) {
0562: XSLTUtils.addAttribute(model, "particleClass", "yes",
0563: rootElt);
0564: }
0565:
0566: if (metainf.isHasParticleType()) {
0567: XSLTUtils.addAttribute(model, "hasParticleType", "yes",
0568: rootElt);
0569: }
0570:
0571: // populate all the information
0572: populateInfo(metainf, model, rootElt, propertyNames, typeMap,
0573: false);
0574:
0575: if (metainf.isSimple() && metainf.isUnion()) {
0576: populateMemberInfo(metainf, model, rootElt, typeMap);
0577: }
0578:
0579: if (metainf.isSimple() && metainf.isList()) {
0580: populateListInfo(metainf, model, rootElt, typeMap);
0581: }
0582: //////////////////////////////////////////////////////////
0583: // System.out.println(DOM2Writer.nodeToString(rootElt));
0584: ////////////////////////////////////////////////////////////
0585:
0586: return rootElt;
0587: }
0588:
0589: protected void populateListInfo(BeanWriterMetaInfoHolder metainf,
0590: Document model, Element rootElement, Map typeMap) {
0591:
0592: String javaName = makeUniqueJavaClassName(new ArrayList(),
0593: metainf.getItemTypeQName().getLocalPart());
0594: Element itemType = XSLTUtils.addChildElement(model, "itemtype",
0595: rootElement);
0596: XSLTUtils.addAttribute(model, "type", metainf
0597: .getItemTypeClassName(), itemType);
0598: XSLTUtils.addAttribute(model, "nsuri", metainf
0599: .getItemTypeQName().getNamespaceURI(), itemType);
0600: XSLTUtils.addAttribute(model, "originalName", metainf
0601: .getItemTypeQName().getLocalPart(), itemType);
0602: XSLTUtils.addAttribute(model, "javaname", javaName, itemType);
0603:
0604: if (typeMap.containsKey(metainf.getItemTypeQName())) {
0605: XSLTUtils.addAttribute(model, "ours", "true", itemType);
0606: }
0607: if (PrimitiveTypeFinder.isPrimitive(metainf
0608: .getItemTypeClassName())) {
0609: XSLTUtils.addAttribute(model, "primitive", "yes", itemType);
0610: }
0611:
0612: String shortTypeName = getShortTypeName(metainf
0613: .getItemTypeClassName());
0614: XSLTUtils.addAttribute(model, "shorttypename", shortTypeName,
0615: itemType);
0616:
0617: }
0618:
0619: protected void populateMemberInfo(BeanWriterMetaInfoHolder metainf,
0620: Document model, Element rootElement, Map typeMap) {
0621: Map memberTypes = metainf.getMemberTypes();
0622: QName memberQName;
0623: for (Iterator iter = memberTypes.keySet().iterator(); iter
0624: .hasNext();) {
0625: memberQName = (QName) iter.next();
0626: String memberClass = (String) memberTypes.get(memberQName);
0627: if (PrimitiveTypeFinder.isPrimitive(memberClass)) {
0628: memberClass = PrimitiveTypeWrapper
0629: .getWrapper(memberClass);
0630: }
0631:
0632: // add member type element
0633: Element memberType = XSLTUtils.addChildElement(model,
0634: "memberType", rootElement);
0635: XSLTUtils.addAttribute(model, "type", memberClass,
0636: memberType);
0637: XSLTUtils.addAttribute(model, "nsuri", memberQName
0638: .getNamespaceURI(), memberType);
0639: XSLTUtils.addAttribute(model, "originalName", memberQName
0640: .getLocalPart(), memberType);
0641: if (typeMap.containsKey(memberQName)) {
0642: XSLTUtils.addAttribute(model, "ours", "true",
0643: memberType);
0644: }
0645: String shortTypeName = getShortTypeName(memberClass);
0646: XSLTUtils.addAttribute(model, "shorttypename",
0647: shortTypeName, memberType);
0648:
0649: }
0650: }
0651:
0652: /**
0653: * @param metainf
0654: * @param model
0655: * @param rootElt
0656: * @param propertyNames
0657: * @param typeMap
0658: * @throws SchemaCompilationException
0659: */
0660: private void populateInfo(BeanWriterMetaInfoHolder metainf,
0661: Document model, Element rootElt, ArrayList propertyNames,
0662: Map typeMap, boolean isInherited)
0663: throws SchemaCompilationException {
0664: // we should add parent class details only if it is
0665: // an extension or simple restriction
0666: // should not in complex restrictions
0667: if (metainf.getParent() != null
0668: && (!metainf.isRestriction() || (metainf
0669: .isRestriction() && metainf.isSimple()))) {
0670: populateInfo(metainf.getParent(), model, rootElt,
0671: propertyNames, typeMap, true);
0672: }
0673: addPropertyEntries(metainf, model, rootElt, propertyNames,
0674: typeMap, isInherited);
0675:
0676: }
0677:
0678: /**
0679: * @param metainf
0680: * @param model
0681: * @param rootElt
0682: * @param propertyNames
0683: * @param typeMap
0684: * @throws SchemaCompilationException
0685: */
0686: private void addPropertyEntries(BeanWriterMetaInfoHolder metainf,
0687: Document model, Element rootElt, ArrayList propertyNames,
0688: Map typeMap, boolean isInherited)
0689: throws SchemaCompilationException {
0690: // go in the loop and add the part elements
0691: QName[] qName;
0692: String javaClassNameForElement;
0693: ArrayList missingQNames = new ArrayList();
0694: ArrayList qNames = new ArrayList();
0695:
0696: BeanWriterMetaInfoHolder parentMetaInf = metainf.getParent();
0697:
0698: if (metainf.isOrdered()) {
0699: qName = metainf.getOrderedQNameArray();
0700: } else {
0701: qName = metainf.getQNameArray();
0702: }
0703:
0704: for (int i = 0; i < qName.length; i++) {
0705: qNames.add(qName[i]);
0706: }
0707: //adding missing QNames to the end, including elements & attributes.
0708: // for the simple types we have already add the parent elements
0709: // it is almost consider as an extension
0710: if (metainf.isRestriction() && !metainf.isSimple()) {
0711: addMissingQNames(metainf, qNames, missingQNames);
0712: }
0713: QName name;
0714:
0715: for (int i = 0; i < qNames.size(); i++) {
0716: name = (QName) qNames.get(i);
0717: Element property = XSLTUtils.addChildElement(model,
0718: "property", rootElt);
0719:
0720: String xmlName = name.getLocalPart();
0721: XSLTUtils.addAttribute(model, "name", xmlName, property);
0722: XSLTUtils.addAttribute(model, "nsuri", name
0723: .getNamespaceURI(), property);
0724:
0725: String javaName = makeUniqueJavaClassName(propertyNames,
0726: xmlName);
0727: // in a restriction if this element already there and array status have changed
0728: // then we have to generate a new name for this
0729: if (parentMetaInf != null
0730: && metainf.isRestriction()
0731: && !missingQNames.contains(name)
0732: && (parentMetaInf.getArrayStatusForQName(name) && !metainf
0733: .getArrayStatusForQName(name))) {
0734: javaName = makeUniqueJavaClassName(propertyNames,
0735: xmlName);
0736: }
0737: XSLTUtils.addAttribute(model, "javaname", javaName,
0738: property);
0739:
0740: if (parentMetaInf != null && metainf.isRestriction()
0741: && missingQNames.contains(name)) {
0742: javaClassNameForElement = parentMetaInf
0743: .getClassNameForQName(name);
0744: } else {
0745: javaClassNameForElement = metainf
0746: .getClassNameForQName(name);
0747: }
0748:
0749: if (javaClassNameForElement == null) {
0750: javaClassNameForElement = getDefaultClassName();
0751: log.warn(SchemaCompilerMessages.getMessage(
0752: "schema.typeMissing", name.toString()));
0753: }
0754:
0755: if (metainf.isRestriction()
0756: && typeChanged(name, missingQNames, metainf)) {
0757: XSLTUtils.addAttribute(model, "typeChanged", "yes",
0758: property);
0759: //XSLTUtils.addAttribute(model, "restricted", "yes", property);
0760: }
0761:
0762: XSLTUtils.addAttribute(model, "type",
0763: javaClassNameForElement, property);
0764:
0765: if (PrimitiveTypeFinder
0766: .isPrimitive(javaClassNameForElement)) {
0767: XSLTUtils.addAttribute(model, "primitive", "yes",
0768: property);
0769: }
0770:
0771: //in the case the original element is an array but the derived one is not.
0772: if (parentMetaInf != null
0773: && metainf.isRestriction()
0774: && !missingQNames.contains(name)
0775: && (parentMetaInf.getArrayStatusForQName(name) && !metainf
0776: .getArrayStatusForQName(name))) {
0777:
0778: XSLTUtils.addAttribute(model, "rewrite", "yes",
0779: property);
0780: XSLTUtils.addAttribute(model, "occuranceChanged",
0781: "yes", property);
0782: } else if (metainf.isRestriction()
0783: && !missingQNames.contains(name)
0784: && (minOccursChanged(name, missingQNames, metainf) || maxOccursChanged(
0785: name, missingQNames, metainf))) {
0786:
0787: XSLTUtils.addAttribute(model, "restricted", "yes",
0788: property);
0789: XSLTUtils.addAttribute(model, "occuranceChanged",
0790: "yes", property);
0791: }
0792:
0793: // set the is particle class
0794: if (metainf.getParticleTypeStatusForQName(name)) {
0795: XSLTUtils.addAttribute(model, "particleClassType",
0796: "yes", property);
0797: }
0798:
0799: // what happed if this contain attributes
0800: // TODO: check the meaning of this removed property
0801:
0802: if (metainf.isRestriction() && missingQNames.contains(name)
0803: && !metainf.isSimple()) {
0804: //XSLTUtils.addAttribute(model, "restricted", "yes", property);
0805: XSLTUtils.addAttribute(model, "removed", "yes",
0806: property);
0807: }
0808:
0809: if (isInherited) {
0810: XSLTUtils.addAttribute(model, "inherited", "yes",
0811: property);
0812: }
0813:
0814: if (metainf.getInnerChoiceStatusForQName(name)) {
0815: XSLTUtils.addAttribute(model, "innerchoice", "yes",
0816: property);
0817: }
0818:
0819: if ((parentMetaInf != null) && metainf.isRestriction()
0820: && missingQNames.contains(name)) {
0821: // this element details should be there with the parent meta Inf
0822: addAttributesToProperty(parentMetaInf, name, model,
0823: property, typeMap, javaClassNameForElement);
0824:
0825: } else {
0826: addAttributesToProperty(metainf, name, model, property,
0827: typeMap, javaClassNameForElement);
0828: }
0829:
0830: } // end of foo
0831: }
0832:
0833: private void addAttributesToProperty(
0834: BeanWriterMetaInfoHolder metainf, QName name,
0835: Document model, Element property, Map typeMap,
0836: String javaClassNameForElement) {
0837: // add an attribute that says the type is default
0838: if (metainf.getDefaultStatusForQName(name)) {
0839: XSLTUtils.addAttribute(model, "default", "yes", property);
0840: }
0841:
0842: if (typeMap.containsKey(metainf.getSchemaQNameForQName(name))) {
0843: XSLTUtils.addAttribute(model, "ours", "yes", property);
0844: }
0845:
0846: if (metainf.getAttributeStatusForQName(name)) {
0847: XSLTUtils.addAttribute(model, "attribute", "yes", property);
0848: }
0849:
0850: if (metainf.isNillable(name)) {
0851: XSLTUtils.addAttribute(model, "nillable", "yes", property);
0852: }
0853:
0854: if (metainf.getOptionalAttributeStatusForQName(name)) {
0855: XSLTUtils.addAttribute(model, "optional", "yes", property);
0856: }
0857:
0858: String shortTypeName;
0859: if (metainf.getSchemaQNameForQName(name) != null) {
0860: // see whether the QName is a basetype
0861: if (baseTypeMap.containsKey(metainf
0862: .getSchemaQNameForQName(name))) {
0863: shortTypeName = metainf.getSchemaQNameForQName(name)
0864: .getLocalPart();
0865: } else {
0866: shortTypeName = getShortTypeName(javaClassNameForElement);
0867: }
0868: } else {
0869: shortTypeName = getShortTypeName(javaClassNameForElement);
0870: }
0871: XSLTUtils.addAttribute(model, "shorttypename", shortTypeName,
0872: property);
0873:
0874: if (metainf.getAnyStatusForQName(name)) {
0875: XSLTUtils.addAttribute(model, "any", "yes", property);
0876: }
0877:
0878: if (metainf.getBinaryStatusForQName(name)) {
0879: XSLTUtils.addAttribute(model, "binary", "yes", property);
0880: }
0881:
0882: if (metainf.isSimple() || metainf.getSimpleStatusForQName(name)) {
0883: XSLTUtils.addAttribute(model, "simple", "yes", property);
0884: }
0885:
0886: // put the min occurs count irrespective of whether it's an array or
0887: // not
0888: long minOccurs = metainf.getMinOccurs(name);
0889: XSLTUtils.addAttribute(model, "minOccurs", minOccurs + "",
0890: property);
0891:
0892: if (metainf.getArrayStatusForQName(name)) {
0893:
0894: XSLTUtils.addAttribute(model, "array", "yes", property);
0895:
0896: int endIndex = javaClassNameForElement.indexOf("[");
0897: if (endIndex >= 0) {
0898: XSLTUtils.addAttribute(model, "arrayBaseType",
0899: javaClassNameForElement.substring(0, endIndex),
0900: property);
0901: } else {
0902: XSLTUtils.addAttribute(model, "arrayBaseType",
0903: javaClassNameForElement, property);
0904: }
0905:
0906: long maxOccurs = metainf.getMaxOccurs(name);
0907: if (maxOccurs == Long.MAX_VALUE) {
0908: XSLTUtils.addAttribute(model, "unbound", "yes",
0909: property);
0910: } else {
0911: XSLTUtils.addAttribute(model, "maxOccurs", maxOccurs
0912: + "", property);
0913: }
0914: }
0915: if (metainf.isRestrictionBaseType(name)) {
0916: XSLTUtils.addAttribute(model, "restrictionBaseType", "yes",
0917: property);
0918: }
0919:
0920: if (metainf.isExtensionBaseType(name)) {
0921: XSLTUtils.addAttribute(model, "extensionBaseType", "yes",
0922: property);
0923: }
0924:
0925: if (metainf.isRestrictionBaseType(name)
0926: && metainf.getLengthFacet() != -1) {
0927: XSLTUtils.addAttribute(model, "lenFacet", metainf
0928: .getLengthFacet()
0929: + "", property);
0930: }
0931:
0932: if (metainf.isRestrictionBaseType(name)
0933: && metainf.getMaxLengthFacet() != -1) {
0934: XSLTUtils.addAttribute(model, "maxLenFacet", metainf
0935: .getMaxLengthFacet()
0936: + "", property);
0937: }
0938:
0939: if (metainf.isRestrictionBaseType(name)
0940: && metainf.getMinLengthFacet() != -1) {
0941: XSLTUtils.addAttribute(model, "minLenFacet", metainf
0942: .getMinLengthFacet()
0943: + "", property);
0944: }
0945:
0946: if (metainf.isRestrictionBaseType(name)
0947: && metainf.getMaxExclusiveFacet() != null) {
0948: XSLTUtils.addAttribute(model, "maxExFacet", metainf
0949: .getMaxExclusiveFacet()
0950: + "", property);
0951: }
0952:
0953: if (metainf.isRestrictionBaseType(name)
0954: && metainf.getMinExclusiveFacet() != null) {
0955: XSLTUtils.addAttribute(model, "minExFacet", metainf
0956: .getMinExclusiveFacet()
0957: + "", property);
0958: }
0959:
0960: if (metainf.isRestrictionBaseType(name)
0961: && metainf.getMaxInclusiveFacet() != null) {
0962: XSLTUtils.addAttribute(model, "maxInFacet", metainf
0963: .getMaxInclusiveFacet()
0964: + "", property);
0965: }
0966:
0967: if (metainf.isRestrictionBaseType(name)
0968: && metainf.getMinInclusiveFacet() != null) {
0969: XSLTUtils.addAttribute(model, "minInFacet", metainf
0970: .getMinInclusiveFacet()
0971: + "", property);
0972: }
0973:
0974: if (!metainf.getEnumFacet().isEmpty()) {
0975: boolean validJava = true; // Assume all enum values are valid ids
0976:
0977: Iterator iterator = metainf.getEnumFacet().iterator();
0978: // Walk the values looking for invalid ids
0979: while (iterator.hasNext()) {
0980: String value = (String) iterator.next();
0981: if (!JavaUtils.isJavaId(value)) {
0982: validJava = false;
0983: }
0984: }
0985:
0986: int id = 0;
0987: iterator = metainf.getEnumFacet().iterator();
0988: while (iterator.hasNext()) {
0989: Element enumFacet = XSLTUtils.addChildElement(model,
0990: "enumFacet", property);
0991: String attribValue = (String) iterator.next();
0992: XSLTUtils.addAttribute(model, "value", attribValue,
0993: enumFacet);
0994: if (validJava) {
0995: XSLTUtils.addAttribute(model, "id", attribValue,
0996: enumFacet);
0997: } else {
0998: id++;
0999: XSLTUtils.addAttribute(model, "id", "value" + id,
1000: enumFacet);
1001: }
1002: }
1003: }
1004:
1005: if (metainf.isRestrictionBaseType(name)
1006: && metainf.getPatternFacet() != null) {
1007: XSLTUtils.addAttribute(model, "patternFacet", metainf
1008: .getPatternFacet(), property);
1009: }
1010: }
1011:
1012: private void addMissingQNames(BeanWriterMetaInfoHolder metainf,
1013: ArrayList qName, ArrayList missingQNames) {
1014:
1015: QName[] qNames = null;
1016: QName[] pQNames = null;
1017:
1018: BeanWriterMetaInfoHolder parentMetaInf = metainf.getParent();
1019:
1020: if (metainf.isOrdered()) {
1021: qNames = metainf.getOrderedQNameArray();
1022: } else {
1023: qNames = metainf.getQNameArray();
1024: }
1025:
1026: if (parentMetaInf != null) {
1027: if (parentMetaInf.isOrdered()) {
1028: pQNames = parentMetaInf.getOrderedQNameArray();
1029: } else {
1030: pQNames = parentMetaInf.getQNameArray();
1031: }
1032: }
1033:
1034: for (int i = 0; pQNames != null && i < pQNames.length; i++) {
1035: if (qNameNotFound(pQNames[i], metainf)) {
1036: missingQNames.add(pQNames[i]);
1037: }
1038: }
1039: //adding missing QNames to the end of list.
1040: if (!missingQNames.isEmpty()) {
1041: for (int i = 0; i < missingQNames.size(); i++) {
1042: qName.add(missingQNames.get(i));
1043: }
1044: }
1045:
1046: }
1047:
1048: private boolean qNameNotFound(QName qname,
1049: BeanWriterMetaInfoHolder metainf) {
1050:
1051: boolean found = false;
1052: QName[] qNames;
1053:
1054: if (metainf.isOrdered()) {
1055: qNames = metainf.getOrderedQNameArray();
1056: } else {
1057: qNames = metainf.getQNameArray();
1058: }
1059:
1060: for (int j = 0; j < qNames.length; j++) {
1061: if (qname.getLocalPart().equals(qNames[j].getLocalPart())) {
1062: found = true;
1063: }
1064: }
1065: return !found;
1066: }
1067:
1068: private boolean typeChanged(QName qname, ArrayList missingQNames,
1069: BeanWriterMetaInfoHolder metainf) {
1070:
1071: boolean typeChanged = false;
1072: QName[] pQNames;
1073:
1074: BeanWriterMetaInfoHolder parentMetainf = metainf.getParent();
1075:
1076: if (parentMetainf != null && !missingQNames.contains(qname)) {
1077:
1078: if (parentMetainf.isOrdered()) {
1079: pQNames = parentMetainf.getOrderedQNameArray();
1080: } else {
1081: pQNames = parentMetainf.getQNameArray();
1082: }
1083:
1084: for (int j = 0; j < pQNames.length; j++) {
1085: if (qname.getLocalPart().equals(
1086: pQNames[j].getLocalPart())) {
1087:
1088: String javaClassForParentElement = parentMetainf
1089: .getClassNameForQName(pQNames[j]);
1090: String javaClassForElement = metainf
1091: .getClassNameForQName(qname);
1092:
1093: if (!javaClassForParentElement
1094: .equals(javaClassForElement)) {
1095: if (javaClassForParentElement.endsWith("[]")) {
1096: if ((javaClassForParentElement.substring(0,
1097: javaClassForParentElement
1098: .indexOf('[')))
1099: .equals(javaClassForElement)) {
1100: continue;
1101: }
1102: } else if (javaClassForElement.endsWith("[]")) {
1103: if ((javaClassForElement.substring(0,
1104: javaClassForElement.indexOf('[')))
1105: .equals(javaClassForParentElement)) {
1106: continue;
1107: }
1108: } else {
1109: typeChanged = true;
1110: }
1111: }
1112: }
1113: }
1114: }
1115: return typeChanged;
1116: }
1117:
1118: private boolean minOccursChanged(QName qname,
1119: ArrayList missingQNames, BeanWriterMetaInfoHolder metainf)
1120: throws SchemaCompilationException {
1121:
1122: boolean minChanged = false;
1123: QName[] pQNames;
1124:
1125: BeanWriterMetaInfoHolder parentMetainf = metainf.getParent();
1126:
1127: if (parentMetainf != null && !missingQNames.contains(qname)) {
1128:
1129: if (parentMetainf.isOrdered()) {
1130: pQNames = parentMetainf.getOrderedQNameArray();
1131: } else {
1132: pQNames = parentMetainf.getQNameArray();
1133: }
1134:
1135: for (int j = 0; j < pQNames.length; j++) {
1136: if (qname.getLocalPart().equals(
1137: pQNames[j].getLocalPart())) {
1138:
1139: if (metainf.getMinOccurs(qname) > parentMetainf
1140: .getMinOccurs(pQNames[j])) {
1141: minChanged = true;
1142: } else if (metainf.getMinOccurs(qname) < parentMetainf
1143: .getMinOccurs(pQNames[j])) {
1144: throw new SchemaCompilationException(
1145: SchemaCompilerMessages
1146: .getMessage("minOccurs Wrong!"));
1147: }
1148:
1149: }
1150: }
1151: }
1152: return minChanged;
1153: }
1154:
1155: private boolean maxOccursChanged(QName qname,
1156: ArrayList missingQNames, BeanWriterMetaInfoHolder metainf)
1157: throws SchemaCompilationException {
1158:
1159: boolean maxChanged = false;
1160: QName[] pQNames;
1161:
1162: BeanWriterMetaInfoHolder parentMetainf = metainf.getParent();
1163:
1164: if (parentMetainf != null && !missingQNames.contains(qname)) {
1165: if (parentMetainf.isOrdered()) {
1166: pQNames = parentMetainf.getOrderedQNameArray();
1167: } else {
1168: pQNames = parentMetainf.getQNameArray();
1169: }
1170:
1171: for (int j = 0; j < pQNames.length; j++) {
1172: if (qname.getLocalPart().equals(
1173: pQNames[j].getLocalPart())) {
1174:
1175: if (metainf.getMaxOccurs(qname) < parentMetainf
1176: .getMaxOccurs(pQNames[j])) {
1177: maxChanged = true;
1178: } else if (metainf.getMaxOccurs(qname) > parentMetainf
1179: .getMaxOccurs(pQNames[j])) {
1180: throw new SchemaCompilationException(
1181: SchemaCompilerMessages
1182: .getMessage("maxOccurs Wrong!"));
1183: }
1184: }
1185: }
1186: }
1187: return maxChanged;
1188: }
1189:
1190: /**
1191: * Test whether the given class name matches the default
1192: *
1193: * @param javaClassNameForElement
1194: */
1195: private boolean isDefault(String javaClassNameForElement) {
1196: return getDefaultClassName().equals(javaClassNameForElement)
1197: || getDefaultClassArrayName().equals(
1198: javaClassNameForElement);
1199: }
1200:
1201: /**
1202: * Given the xml name, make a unique class name taking into account that
1203: * some file systems are case sensitive and some are not. -Consider the
1204: * Jax-WS spec for this
1205: *
1206: * @param listOfNames
1207: * @param xmlName
1208: * @return Returns String.
1209: */
1210: private String makeUniqueJavaClassName(List listOfNames,
1211: String xmlName) {
1212: String javaName;
1213: if (JavaUtils.isJavaKeyword(xmlName)) {
1214: javaName = JavaUtils.makeNonJavaKeyword(xmlName);
1215: } else {
1216: javaName = JavaUtils.capitalizeFirstChar(JavaUtils
1217: .xmlNameToJava(xmlName));
1218: }
1219:
1220: while (listOfNames.contains(javaName.toLowerCase())) {
1221: javaName = javaName + count++;
1222: }
1223:
1224: listOfNames.add(javaName.toLowerCase());
1225: return javaName;
1226: }
1227:
1228: /**
1229: * A bit of code from the old code generator. We are better off using the
1230: * template engines and such stuff that's already there. But the class
1231: * writers are hard to be reused so some code needs to be repeated (atleast
1232: * a bit)
1233: */
1234: private void loadTemplate() throws SchemaCompilationException {
1235:
1236: // first get the language specific property map
1237: Class clazz = this .getClass();
1238: InputStream xslStream;
1239: String templateName = javaBeanTemplateName;
1240: if (templateName != null) {
1241: try {
1242: xslStream = clazz.getResourceAsStream(templateName);
1243: templateCache = TransformerFactory.newInstance()
1244: .newTemplates(new StreamSource(xslStream));
1245: templateLoaded = true;
1246: } catch (TransformerConfigurationException e) {
1247: throw new SchemaCompilationException(
1248: SchemaCompilerMessages
1249: .getMessage("schema.templateLoadException"),
1250: e);
1251: }
1252: } else {
1253: throw new SchemaCompilationException(SchemaCompilerMessages
1254: .getMessage("schema.templateNotFoundException"));
1255: }
1256: }
1257:
1258: /**
1259: * Creates the output file
1260: *
1261: * @param packageName
1262: * @param fileName
1263: * @throws Exception
1264: */
1265: private File createOutFile(String packageName, String fileName)
1266: throws Exception {
1267: return org.apache.axis2.util.FileWriter.createClassFile(
1268: this .rootDir, packageName, fileName, ".java");
1269: }
1270:
1271: /**
1272: * Writes the output file
1273: *
1274: * @param doc
1275: * @param outputFile
1276: * @throws Exception
1277: */
1278: private void parse(Document doc, File outputFile) throws Exception {
1279: OutputStream outStream = new FileOutputStream(outputFile);
1280: XSLTTemplateProcessor.parse(outStream, doc, getTransformer());
1281: outStream.flush();
1282: outStream.close();
1283:
1284: PrettyPrinter.prettify(outputFile);
1285: }
1286:
1287: private Transformer getTransformer()
1288: throws TransformerConfigurationException,
1289: SchemaCompilationException {
1290: try {
1291: return this .templateCache.newTransformer();
1292: } catch (Exception e) {
1293: // Under some peculiar conditions (classloader issues), just scrap the old templateCache,
1294: // create a new one and try again.
1295: loadTemplate();
1296: return this .templateCache.newTransformer();
1297: }
1298: }
1299:
1300: /**
1301: * Get a prefix for a namespace URI. This method will ALWAYS return a valid
1302: * prefix - if the given URI is already mapped in this serialization, we
1303: * return the previous prefix. If it is not mapped, we will add a new
1304: * mapping and return a generated prefix of the form "ns<num>".
1305: *
1306: * @param uri is the namespace uri
1307: * @return Returns prefix.
1308: */
1309: public String getPrefixForURI(String uri) {
1310: return getPrefixForURI(uri, null);
1311: }
1312:
1313: /**
1314: * Last used index suffix for "ns"
1315: */
1316: private int lastPrefixIndex = 1;
1317:
1318: /**
1319: * Map of namespaces URI to prefix(es)
1320: */
1321: HashMap mapURItoPrefix = new HashMap();
1322:
1323: HashMap mapPrefixtoURI = new HashMap();
1324:
1325: /**
1326: * Get a prefix for the given namespace URI. If one has already been defined
1327: * in this serialization, use that. Otherwise, map the passed default prefix
1328: * to the URI, and return that. If a null default prefix is passed, use one
1329: * of the form "ns<num>"
1330: */
1331: public String getPrefixForURI(String uri, String defaultPrefix) {
1332: if ((uri == null) || (uri.length() == 0))
1333: return null;
1334: String prefix = (String) mapURItoPrefix.get(uri);
1335: if (prefix == null) {
1336: if (defaultPrefix == null || defaultPrefix.length() == 0) {
1337: prefix = "ns" + lastPrefixIndex++;
1338: while (mapPrefixtoURI.get(prefix) != null) {
1339: prefix = "ns" + lastPrefixIndex++;
1340: }
1341: } else {
1342: prefix = defaultPrefix;
1343: }
1344: mapPrefixtoURI.put(prefix, uri);
1345: mapURItoPrefix.put(uri, prefix);
1346: }
1347: return prefix;
1348: }
1349:
1350: private String getShortTypeName(String typeClassName) {
1351: if (typeClassName.endsWith("[]")) {
1352: typeClassName = typeClassName.substring(0, typeClassName
1353: .lastIndexOf("["));
1354: }
1355:
1356: return typeClassName.substring(
1357: typeClassName.lastIndexOf(".") + 1, typeClassName
1358: .length());
1359:
1360: }
1361:
1362: /**
1363: * Get the mapper class name - there is going to be only one
1364: * mapper class for the whole
1365: */
1366: private String getFullyQualifiedMapperClassName() {
1367: if (wrapClasses || !writeClasses) {
1368: return EXTENSION_MAPPER_CLASSNAME;
1369: } else {
1370: return mappingClassPackage + "."
1371: + EXTENSION_MAPPER_CLASSNAME;
1372: }
1373: }
1374:
1375: /**
1376: * get the mapper class package name
1377: * May be ignored by the implementer
1378: */
1379: public String getExtensionMapperPackageName() {
1380: return mappingClassPackage;
1381: }
1382:
1383: /**
1384: * Sets the mapping class name of this writer. A mapping class
1385: * package set by the options may be overridden at the this point
1386: *
1387: * @param mapperPackageName
1388: */
1389: public void registerExtensionMapperPackageName(
1390: String mapperPackageName) {
1391: this .mappingClassPackage = mapperPackageName;
1392: }
1393:
1394: /**
1395: * Write the extension classes - this is needed to process
1396: * the hierarchy of classes
1397: *
1398: * @param metainfArray
1399: */
1400: public void writeExtensionMapper(
1401: BeanWriterMetaInfoHolder[] metainfArray)
1402: throws SchemaCompilationException {
1403: //generate the element
1404: try {
1405:
1406: String mapperClassName = getFullyQualifiedMapperClassName();
1407:
1408: Document model = XSLTUtils.getDocument();
1409: Element rootElt = XSLTUtils.getElement(model, "mapper");
1410: String mapperName = mapperClassName
1411: .substring(mapperClassName.lastIndexOf(".") + 1);
1412: XSLTUtils.addAttribute(model, "name", mapperName, rootElt);
1413: String basePackageName = "";
1414: if (mapperClassName.indexOf(".") != -1) {
1415: basePackageName = mapperClassName.substring(0,
1416: mapperClassName.lastIndexOf("."));
1417: XSLTUtils.addAttribute(model, "package",
1418: basePackageName, rootElt);
1419: } else {
1420: XSLTUtils.addAttribute(model, "package", "", rootElt);
1421: }
1422:
1423: if (!wrapClasses) {
1424: XSLTUtils.addAttribute(model, "unwrapped", "yes",
1425: rootElt);
1426: }
1427:
1428: if (!writeClasses) {
1429: XSLTUtils.addAttribute(model, "skip-write", "yes",
1430: rootElt);
1431: }
1432:
1433: if (isHelperMode) {
1434: XSLTUtils.addAttribute(model, "helpermode", "yes",
1435: rootElt);
1436: }
1437:
1438: for (int i = 0; i < metainfArray.length; i++) {
1439: QName ownQname = metainfArray[i].getOwnQname();
1440: String className = metainfArray[i].getOwnClassName();
1441: //do not add when the qname is not availble
1442: if (ownQname != null) {
1443: Element typeChild = XSLTUtils.addChildElement(
1444: model, "type", rootElt);
1445: XSLTUtils.addAttribute(model, "nsuri", ownQname
1446: .getNamespaceURI(), typeChild);
1447: XSLTUtils.addAttribute(model, "classname",
1448: className == null ? "" : className,
1449: typeChild);
1450: XSLTUtils.addAttribute(model, "shortname",
1451: ownQname == null ? "" : ownQname
1452: .getLocalPart(), typeChild);
1453: }
1454: }
1455:
1456: model.appendChild(rootElt);
1457:
1458: if (!templateLoaded) {
1459: loadTemplate();
1460: }
1461:
1462: if (wrapClasses) {
1463: rootElt = (Element) globalWrappedDocument.importNode(
1464: rootElt, true);
1465: //add to the global wrapped document
1466: globalWrappedDocument.getDocumentElement().appendChild(
1467: rootElt);
1468: } else {
1469: if (writeClasses) {
1470: // create the file
1471: File out = createOutFile(basePackageName,
1472: mapperName);
1473: // parse with the template and create the files
1474: parse(model, out);
1475:
1476: }
1477:
1478: // add the model to the model map
1479: modelMap.put(new QName(mapperName), model);
1480: }
1481:
1482: } catch (ParserConfigurationException e) {
1483: throw new SchemaCompilationException(SchemaCompilerMessages
1484: .getMessage("schema.docuement.error"), e);
1485: } catch (Exception e) {
1486: e.printStackTrace();
1487: throw new SchemaCompilationException(e);
1488: }
1489:
1490: }
1491:
1492: }
|