0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.schema2beansdev;
0043:
0044: import java.util.*;
0045: import java.io.*;
0046:
0047: import org.netbeans.modules.schema2beans.*;
0048: import org.netbeans.modules.schema2beansdev.metadd.*;
0049: import org.netbeans.modules.schema2beansdev.gen.*;
0050:
0051: public abstract class AbstractCodeGeneratorClass {
0052: static class Property {
0053: String dtdName;
0054: private String namespace;
0055: String name;
0056: String classType;
0057: int type;
0058: int elementInstance;
0059: int groupInstance;
0060: int level;
0061: boolean isBean;
0062: boolean ored;
0063: boolean isUnion = false;
0064: String constName;
0065: private boolean nillable;
0066: private boolean _isAttribute;
0067: private AttrProp attrProp;
0068: private Property attributeOwner = null;
0069: private String defaultValue;
0070: private boolean directChild;
0071: private GraphNode graphNode;
0072: private GraphLink graphLink;
0073: private List extraData;
0074: private boolean canBeEmpty = false;
0075: private String propertyInterface = null;
0076: private transient List mutuallyExclusiveProperties;
0077: private BeanBuilder.BeanElement beanElement;
0078: //private String orGroupName;
0079:
0080: // List of attributes for this property (might be empty)
0081: AttrProp[] attributes;
0082:
0083: Property(String propName, String dtdName, String namespace,
0084: GraphNode graphNode, GraphLink graphLink,
0085: String classType, int eInst, int gInst, int level,
0086: int type, boolean ored, AttrProp[] attrs,
0087: String constName, String defaultValue,
0088: boolean directChild, List extraData, boolean isUnion) {
0089: //
0090: // If the group instance is array, the element instance
0091: // becomes an array.
0092: //
0093: if (gInst == Common.TYPE_0_N)
0094: eInst = gInst;
0095: else if (gInst == Common.TYPE_1_N) {
0096: if (eInst == Common.TYPE_0_1)
0097: eInst = Common.TYPE_0_N;
0098: else
0099: eInst = Common.TYPE_1_N;
0100: }
0101:
0102: this .name = propName;
0103: this .isUnion = isUnion;
0104: this .dtdName = dtdName;
0105: this .namespace = namespace;
0106: this .graphNode = graphNode;
0107: this .graphLink = graphLink;
0108: this .classType = classType;
0109: this .type = type;
0110: this .elementInstance = eInst;
0111: this .groupInstance = gInst;
0112: this .level = level;
0113: this .attributes = attrs;
0114: this .ored = ored;
0115: this .constName = constName;
0116: this .isBean = Common.isBean(type);
0117: if (isScalar()) {
0118: this .classType = Common.wrapperClass(type);
0119: }
0120: this .defaultValue = defaultValue;
0121: this .directChild = directChild;
0122: this .extraData = extraData;
0123: //System.out.println("New property: name="+name+" type="+type);
0124: }
0125:
0126: public boolean isIndexed() {
0127: if (elementInstance == Common.TYPE_1_N) {
0128: return true;
0129: } else if (elementInstance == Common.TYPE_0_N) {
0130: return true;
0131: }
0132: return false;
0133: }
0134:
0135: public void setIndexed(boolean value) {
0136: if (isIndexed() == value)
0137: return;
0138: if (value)
0139: elementInstance = Common.TYPE_0_N;
0140: else
0141: elementInstance = Common.TYPE_0_1;
0142: }
0143:
0144: public boolean isNillable() {
0145: return nillable;
0146: }
0147:
0148: public void setNillable(boolean value) {
0149: nillable = value;
0150: }
0151:
0152: public boolean isUnion() {
0153: return isUnion;
0154: }
0155:
0156: public void setUnion(boolean value) {
0157: isUnion = value;
0158: }
0159:
0160: public boolean isScalar() {
0161: return Common.isScalar(type);
0162: }
0163:
0164: public String getScalarType() {
0165: if (!isScalar())
0166: return null;
0167: return Common.scalarType(type);
0168: }
0169:
0170: /**
0171: * The java type used for this bean. @see getSignatureType()
0172: */
0173: public String getType() {
0174: if (isScalar())
0175: return getScalarType();
0176: else
0177: return classType;
0178: }
0179:
0180: public void setAttribute(boolean value) {
0181: _isAttribute = value;
0182: }
0183:
0184: public boolean isAttribute() {
0185: return _isAttribute;
0186: }
0187:
0188: public void setAttrProp(AttrProp ap) {
0189: attrProp = ap;
0190: setAttribute(ap != null);
0191: }
0192:
0193: public AttrProp getAttrProp() {
0194: return attrProp;
0195: }
0196:
0197: public void setAttributeOwner(Property owner) {
0198: attributeOwner = owner;
0199: }
0200:
0201: public Property getAttributeOwner() {
0202: return attributeOwner;
0203: }
0204:
0205: public String getDefaultValue() {
0206: return defaultValue;
0207: }
0208:
0209: public boolean isDirectChild() {
0210: return directChild;
0211: }
0212:
0213: public int getGroupInstance() {
0214: return groupInstance;
0215: }
0216:
0217: /**
0218: * The canBeEmpty property is true only if this node can be EMPTY
0219: * or not there. This only occurs for when a DTD says that an
0220: * element is EMPTY and that maps into a boolean.
0221: */
0222: public void setCanBeEmpty(boolean value) {
0223: canBeEmpty = value;
0224: }
0225:
0226: public boolean getCanBeEmpty() {
0227: return canBeEmpty;
0228: }
0229:
0230: /**
0231: * This may return null.
0232: */
0233: public GraphNode getGraphNode() {
0234: return graphNode;
0235: }
0236:
0237: /**
0238: * This GraphLink is the one that defined this property's name.
0239: * It's siblings are the siblings in the schema.
0240: * This may return null.
0241: * getGraphLink().element == getGraphNode()
0242: */
0243: public GraphLink getGraphLink() {
0244: return graphLink;
0245: }
0246:
0247: public void setPropertyInterface(String iface) {
0248: propertyInterface = iface;
0249: }
0250:
0251: /**
0252: * The property interface is nonnull if the getters/setters
0253: * are suppose to use this interface.
0254: */
0255: public String getPropertyInterface() {
0256: return propertyInterface;
0257: }
0258:
0259: /**
0260: * This is the java type name as seen in the signature. Usually, this
0261: * is the same as getTypeFullClassName(), but can
0262: * differ if -useInterfaces was set.
0263: */
0264: public String getSignatureType(String packageName) {
0265: if (getPropertyInterface() == null)
0266: return getTypeFullClassName(packageName);
0267: else
0268: return getPropertyInterface();
0269: }
0270:
0271: public String getTypeFullClassName(String packageName) {
0272: return getTypeFullClassName(packageName, getType());
0273: }
0274:
0275: public String getTypeFullClassName(String packageName,
0276: String typeName) {
0277: if (isBean && getGraphNode().isCreated()
0278: && packageName != null)
0279: return packageName + "." + typeName;
0280: return typeName;
0281: }
0282:
0283: public String getDTDName() {
0284: return dtdName;
0285: }
0286:
0287: public String getNamespace() {
0288: return namespace;
0289: }
0290:
0291: public BeanBuilder.BeanElement getBeanElement() {
0292: return beanElement;
0293: }
0294:
0295: public void setBeanElement(BeanBuilder.BeanElement be) {
0296: beanElement = be;
0297: }
0298:
0299: public String instanceOf() {
0300: String result = java.beans.Introspector.decapitalize(name);
0301: while (JavaUtil.reservedWord(result))
0302: result = "a_" + result;
0303: return result;
0304: }
0305:
0306: public String beanIntrospectorName() {
0307: return java.beans.Introspector.decapitalize(name);
0308: }
0309:
0310: public String getEventName() {/*
0311: if (isAttribute() && getAttributeOwner() != null &&
0312: getAttributeOwner() != this) {
0313: return getAttributeOwner().constName+"@"+getAttrProp().getDtdName();
0314: } else */
0315: return name;
0316: }
0317:
0318: /**
0319: * @param withIndexedParameter whether or not this getter
0320: * is going to be called with an index as a parameter.
0321: * @return the method to be called to do a read.
0322: */
0323: public String getReadMethod(boolean withIndexParameter) {
0324: if (!withIndexParameter && isIndexed())
0325: return "get" + name;
0326: else if (isScalar() && Common.isBoolean(type))
0327: return "is" + name;
0328: else
0329: return "get" + name;
0330: }
0331:
0332: public String getWriteMethod() {
0333: return "set" + name;
0334: }
0335:
0336: public String getAddMethod() {
0337: return "add" + name;
0338: }
0339:
0340: public String getRemoveMethod() {
0341: return "remove" + name;
0342: }
0343:
0344: public String getSizeMethod() {
0345: return "size" + name;
0346: }
0347:
0348: public String getScalarIsSet() {
0349: return "_isSet_" + name;
0350: }
0351:
0352: public List getMutuallyExclusiveProperties() {
0353: if (mutuallyExclusiveProperties == null
0354: && graphLink != null) {
0355: // Get the mutually exclusive GraphLink's and extract
0356: // our properties out of them.
0357: List mutuallyExclusiveGraphLinks = new ArrayList();
0358: graphLink
0359: .getMutuallyExclusiveLinks(mutuallyExclusiveGraphLinks);
0360: mutuallyExclusiveProperties = new ArrayList(
0361: mutuallyExclusiveGraphLinks.size());
0362: for (Iterator it = mutuallyExclusiveGraphLinks
0363: .iterator(); it.hasNext();) {
0364: GraphLink l = (GraphLink) it.next();
0365: if (l.getObject() != null)
0366: mutuallyExclusiveProperties.add(l.getObject());
0367: }
0368: }
0369: return mutuallyExclusiveProperties;
0370: }
0371:
0372: /*
0373: public String getOrGroupName() {
0374: if (orGroupName == null) {
0375: orGroupName = name;
0376: for (Iterator it = getMutuallyExclusiveProperties().iterator(); it.hasNext(); ) {
0377: Property p = (Property) it.next();
0378: orGroupName += p.name;
0379: }
0380: for (Iterator it = getMutuallyExclusiveProperties().iterator(); it.hasNext(); ) {
0381: Property p = (Property) it.next();
0382: p.orGroupName = orGroupName;
0383: }
0384: }
0385: return orGroupName;
0386: }
0387: */
0388:
0389: public boolean canBeNull() {
0390: boolean canBeNull = false;
0391: boolean isPrimitiveType = JavaUtil
0392: .isPrimitiveType(getType());
0393: if (ored) {
0394: canBeNull = !isPrimitiveType;
0395: } else {
0396: switch (elementInstance & Common.MASK_INSTANCE) {
0397: case Common.TYPE_0_1:
0398: case Common.TYPE_1_N:
0399: case Common.TYPE_0_N:
0400: canBeNull = !isPrimitiveType;
0401: break;
0402: }
0403: }
0404: // What about group instance?
0405: return canBeNull;
0406: }
0407:
0408: public Object searchExtraData(Class type) {
0409: for (Iterator it = extraData.iterator(); it.hasNext();) {
0410: Object o = it.next();
0411: //System.out.println("searchExtraData: o="+o);
0412: if (type.isAssignableFrom(o.getClass()))
0413: return o;
0414: }
0415: return null;
0416: }
0417:
0418: public Iterator extraDataIterator() {
0419: return extraData.iterator();
0420: }
0421: }
0422:
0423: class PropertyVisitor {
0424: protected Property curProp;
0425: protected int propNum;
0426: protected int propCount;
0427:
0428: public PropertyVisitor() {
0429: }
0430:
0431: public void generate() throws IOException {
0432: propCount = attrList.size();
0433: preGenerate();
0434: for (propNum = 0; propNum < propCount; ++propNum) {
0435: curProp = (Property) attrList.get(propNum);
0436: if (skip())
0437: continue;
0438: preGenerateProp();
0439: generateProp();
0440: postGenerateProp();
0441: }
0442: postGenerate();
0443: }
0444:
0445: public void preGenerate() throws IOException {
0446: }
0447:
0448: public boolean skip() {
0449: return false;
0450: }
0451:
0452: public void preGenerateProp() throws IOException {
0453: }
0454:
0455: public void generateProp() throws IOException {
0456: }
0457:
0458: public void postGenerateProp() throws IOException {
0459: }
0460:
0461: public void postGenerate() throws IOException {
0462: }
0463: }
0464:
0465: class NamePropertyVisitor extends PropertyVisitor {
0466: protected String nameVar;
0467:
0468: public NamePropertyVisitor(String nameVar) {
0469: this .nameVar = nameVar;
0470: }
0471:
0472: public void preGenerate() throws IOException {
0473: jw.writeEol(nameVar + " = " + nameVar + ".intern()");
0474: }
0475:
0476: public void preGenerateProp() throws IOException {
0477: if (curProp.name.equals(curProp.dtdName))
0478: jw.beginIf(nameVar + " == " + curProp.constName);
0479: else
0480: jw.beginIf(nameVar + " == " + curProp.constName
0481: + " || " + nameVar + " == \"" + curProp.dtdName
0482: + "\"");
0483: }
0484:
0485: public void postGenerateProp() throws IOException {
0486: jw.endElse();
0487: }
0488:
0489: public void postGenerate() throws IOException {
0490: genInvalidName(nameVar);
0491: }
0492: }
0493:
0494: protected void genInvalidName(String var) throws IOException {
0495: jw.writeEol("throw new IllegalArgumentException(", var,
0496: "+\" is not a valid property name for ", className
0497: + "\")");
0498: }
0499:
0500: protected GenBeans.Config config;
0501: protected String packageName;
0502: protected String className;
0503: protected String fullClassName;
0504:
0505: protected BeanBuilder.BeanElement beanElement;
0506: protected BeanBuilder.BeanElement rootBeanElement;
0507:
0508: private String defaultNamespace = null;
0509:
0510: // the graph of meta-elements
0511: protected MetaDD mdd;
0512:
0513: // the meta-element for this class
0514: protected MetaElement metaElement;
0515:
0516: // the set of types we've generated create methods for.
0517: protected Map generatedNewMethods = new HashMap(); // Map<String, String>
0518:
0519: // The list of all the attribute of this bean class
0520: protected ArrayList attrList;
0521:
0522: protected PrefixGuesser prefixGuesser;
0523:
0524: // Current building stream
0525: protected int HEADER_SECTION = 0;
0526: protected int DECL_SECTION = 1;
0527: protected int CONSTRUCTOR_SECTION = 2;
0528: protected int INITIALIZE_SECTION = 3;
0529: protected int ACCESS_SECTION = 4;
0530: protected int NEW_METHOD_SECTION = 5;
0531: protected int BODY_SECTION = 6;
0532: protected int EQUALS_SECTION = 7;
0533: protected int HASHCODE_SECTION = 8;
0534: protected int TRAILER_SECTION = 9;
0535: protected int MAXVALUE = 10;
0536:
0537: JavaWriter jw;
0538:
0539: private Map mutableTypes = new HashMap();
0540: private Map needToCallClone = new HashMap();
0541:
0542: protected boolean isMutableType(Property prop) {
0543: String type = prop.getType();
0544: Boolean mutable = (Boolean) mutableTypes.get(type);
0545: if (mutable == null) {
0546: if (prop.isBean)
0547: mutable = Boolean.TRUE;
0548: else if (prop.isScalar() || JavaUtil.isImmutable(type))
0549: mutable = Boolean.FALSE;
0550: else
0551: mutable = Boolean.TRUE;
0552: mutableTypes.put(type, mutable);
0553: }
0554: return mutable.booleanValue();
0555: }
0556:
0557: protected boolean isCloneCallNeededOnType(Property prop) {
0558: String type = prop.getType();
0559: Boolean callClone = (Boolean) needToCallClone.get(type);
0560: if (callClone == null) {
0561: if (prop.isBean || !isMutableType(prop))
0562: callClone = Boolean.FALSE;
0563: else
0564: callClone = JavaUtil.isCloneable(type) ? Boolean.TRUE
0565: : Boolean.FALSE;
0566: needToCallClone.put(type, callClone);
0567: }
0568: return callClone.booleanValue();
0569: }
0570:
0571: protected boolean genCopyWillCopy(Property a) {
0572: String type = a.getType();
0573: boolean mutable = isMutableType(a);
0574: boolean needToCallClone = isCloneCallNeededOnType(a);
0575: if ((mutable || needToCallClone) && !a.isBean
0576: && !JavaUtil.isInstantiable(type)) {
0577: mutable = false;
0578: needToCallClone = false;
0579: }
0580: if (type == "java.io.File") {
0581: return true;
0582: } else if (needToCallClone) {
0583: return true;
0584: } else if (mutable) {
0585: return true;
0586: } else {
0587: return false;
0588: }
0589: }
0590:
0591: protected void genCopy(String src, Property a, String justData)
0592: throws IOException {
0593: String type = a.getType().intern();
0594: String fullClassType = getTypeFullClassName(a);
0595: boolean mutable = isMutableType(a);
0596: boolean needToCallClone = isCloneCallNeededOnType(a);
0597: if ((mutable || needToCallClone) && !a.isBean
0598: && !JavaUtil.isInstantiable(type)) {
0599: mutable = false;
0600: needToCallClone = false;
0601: }
0602: if (type == "java.io.File") {
0603: jw.write("(", src, " == null) ? null : ");
0604: gen("new ");
0605: gen(fullClassType);
0606: PO();
0607: jw.write(src);
0608: jw.write(".getAbsolutePath()");
0609: PC();
0610: } else if (needToCallClone) {
0611: jw.write("(", src, " == null) ? null : ");
0612: PO();
0613: gen(fullClassType);
0614: PC();
0615: gen(src);
0616: gen(".clone()");
0617: } else if (mutable) {
0618: jw.write("(", src, " == null) ? null : ");
0619: String castSourceTo = null;
0620: if (a.isBean && hasDeepCopyConstructor()) {
0621: castSourceTo = a.getPropertyInterface();
0622: if (a.getPropertyInterface() != null
0623: && !type.equals(a.getPropertyInterface()))
0624: jw.write("(", type, ") ");
0625: jw.write(genNewMethod(a.getPropertyInterface(), type));
0626: } else {
0627: gen("new ");
0628: gen(fullClassType);
0629: }
0630:
0631: PO();
0632: if (castSourceTo != null)
0633: jw.write("(", castSourceTo, ") ");
0634: jw.write(src);
0635: if (a.isBean) {
0636: if (config.isGenerateParentRefs()) {
0637: jw.write(", this");
0638: }
0639: jw.write(", ", justData);
0640: }
0641: PC();
0642: } else {
0643: jw.write(src);
0644: }
0645: }
0646:
0647: protected boolean isTypeQName(String type) {
0648: type = type.intern();
0649: if (type == "javax.xml.namespace.QName")
0650: return true;
0651: if (type == "org.netbeans.modules.schema2beans.QName")
0652: return true;
0653: return false;
0654: }
0655:
0656: //
0657: // Initial values for tabulations. Only header is 0, all other
0658: // parts of the class start at one tabulation
0659: //
0660:
0661: static protected final int PUBLIC = 0;
0662: static protected final int PRIVATE = 1;
0663: static protected final int VOID = 2;
0664: static protected final int CLASS = 3;
0665: static protected final int IMPORT = 4;
0666: static protected final int PACKAGE = 5;
0667: static protected final int STRING = 6;
0668: static protected final int BOOLEAN = 7;
0669: static protected final int STATIC = 8;
0670: static protected final int FINAL = 9;
0671: static protected final int INT = 10;
0672: static protected final int PROTECTED = 11;
0673:
0674: static protected final String arrKeywords[] = { "public",
0675: "private", "void", "class", "import", "package", "String",
0676: "boolean", "static", "final", "int", "protected" };
0677:
0678: protected void init(BeanBuilder.BeanElement be,
0679: GenBeans.Config config) {
0680: this .config = config;
0681: beanElement = be;
0682: packageName = null;
0683: className = be.getClassType();
0684: fullClassName = className;
0685: attrList = new ArrayList();
0686: jw = new JavaWriter();
0687: HEADER_SECTION = jw.HEADER_SECTION;
0688: DECL_SECTION = jw.DECL_SECTION;
0689: CONSTRUCTOR_SECTION = jw.CONSTRUCTOR_SECTION;
0690: INITIALIZE_SECTION = jw
0691: .insertSectionAfter(jw.CONSTRUCTOR_SECTION);
0692: ACCESS_SECTION = jw.insertSectionAfter(INITIALIZE_SECTION);
0693: NEW_METHOD_SECTION = jw.insertSectionAfter(ACCESS_SECTION);
0694: BODY_SECTION = jw.BODY_SECTION;
0695: EQUALS_SECTION = jw.insertSectionAfter(BODY_SECTION);
0696: HASHCODE_SECTION = jw.insertSectionAfter(EQUALS_SECTION);
0697: resetGenBuffers();
0698: }
0699:
0700: protected void resetGenBuffers() {
0701: jw.reset();
0702: jw.select(HEADER_SECTION);
0703: }
0704:
0705: protected void printGenBuffers(OutputStream out) throws IOException {
0706: jw.writeTo(out);
0707: }
0708:
0709: public void setPackageName(String n) {
0710: if (n == null || "".equals(n)) {
0711: packageName = null;
0712: fullClassName = className;
0713: } else {
0714: packageName = n.replace('/', '.');
0715: fullClassName = packageName + "." + className;
0716: }
0717: }
0718:
0719: public void setDefaultNamespace(String ns) {
0720: defaultNamespace = ns;
0721: }
0722:
0723: public String getDefaultNamespace() {
0724: return defaultNamespace;
0725: }
0726:
0727: /**
0728: * @param a is the Property in question
0729: * @param typeName is the name of the type of @param a, could include "[]"
0730: * @return Only if @param a is a bean will we add the packageName
0731: * to it's front.
0732: */
0733: protected String getTypeFullClassName(Property a) {
0734: return a.getTypeFullClassName(packageName);
0735: }
0736:
0737: protected String getTypeFullClassName(Property a, String typeName) {
0738: return a.getTypeFullClassName(packageName, typeName);
0739: }
0740:
0741: public void setIndent(String indent) {
0742: jw.setIndent(indent);
0743: }
0744:
0745: public void setRootBeanElement(BeanBuilder.BeanElement element) {
0746: rootBeanElement = element;
0747: }
0748:
0749: private transient String cachedRootClassName = null;
0750:
0751: protected String getRootClassName() {
0752: if (cachedRootClassName == null) {
0753: String rootClassName = rootBeanElement.getClassType();
0754: if (packageName == null)
0755: cachedRootClassName = rootClassName;
0756: else
0757: cachedRootClassName = packageName + "." + rootClassName;
0758: }
0759: return cachedRootClassName;
0760: }
0761:
0762: /**
0763: * Once all properties have been added to this Bean, call this method
0764: * to figure out for attribute property who it's owner is.
0765: * That is, make Property.getAttributeOwner() work.
0766: */
0767: protected void findAttributeOwners() {
0768: Property attributeOwner;
0769: int size = attrList.size();
0770: for (int i = 0; i < size; i++) {
0771: Property a = (Property) attrList.get(i);
0772: if (a.isAttribute()) {
0773: attributeOwner = a;
0774: AttrProp attrProp = a.getAttrProp();
0775: propertyLoop: for (int propNum = 0; propNum < size; ++propNum) {
0776: Property prop = (Property) attrList.get(propNum);
0777: if (prop.attributes == null)
0778: continue;
0779: for (int attrNum = 0; attrNum < prop.attributes.length; ++attrNum) {
0780: AttrProp propAttr = prop.attributes[attrNum];
0781: if (propAttr == attrProp) {
0782: // Found it!
0783: attributeOwner = prop;
0784: break propertyLoop;
0785: }
0786: }
0787: }
0788: a.setAttributeOwner(attributeOwner);
0789: a.setIndexed(attributeOwner.isIndexed());
0790: }
0791: }
0792: }
0793:
0794: /**
0795: * @return null if not found
0796: */
0797: protected Property findProperty(AttrProp attr) {
0798: int size = attrList.size();
0799: for (int j = 0; j < size; j++) {
0800: Property p = (Property) attrList.get(j);
0801: if (p.getAttrProp() == attr) {
0802: // Found it
0803: return p;
0804: }
0805: }
0806: return null;
0807: }
0808:
0809: /*
0810: * Set of helpers to generate the classe content
0811: */
0812: protected void select(int o) {
0813: jw.select(o);
0814: }
0815:
0816: protected void gen(String s) {
0817: try {
0818: jw.write(s);
0819: } catch (IOException e) {
0820: throw new RuntimeException(e);
0821: }
0822: }
0823:
0824: protected void gen(StringBuffer s) {
0825: try {
0826: jw.write(s);
0827: } catch (IOException e) {
0828: throw new RuntimeException(e);
0829: }
0830: }
0831:
0832: protected void gen(String s1, String s2) {
0833: gen(s1);
0834: gen(s2);
0835: }
0836:
0837: protected void gen(String s1, String s2, String s3) {
0838: gen(s1);
0839: gen(s2);
0840: gen(s3);
0841: }
0842:
0843: protected void gen(int a) {
0844: gen(arrKeywords[a]);
0845: }
0846:
0847: protected void gen(int a, String s) {
0848: gen(a);
0849: sp();
0850: gen(s);
0851: }
0852:
0853: protected void gen(int a, String s, String s2) {
0854: gen(a, s);
0855: sp();
0856: gen(s2);
0857: }
0858:
0859: protected void gen(int a, int b, String s, String s2) {
0860: gen(a, b, s);
0861: gen(s2);
0862: }
0863:
0864: protected void gen(int a, int b, String s) {
0865: gen(a);
0866: sp();
0867: gen(b);
0868: sp();
0869: gen(s);
0870: }
0871:
0872: protected void gen(int a, int b, int c, String s) {
0873: gen(a);
0874: sp();
0875: gen(b);
0876: sp();
0877: gen(c);
0878: sp();
0879: gen(s);
0880: }
0881:
0882: protected void gen(int a, int b, int c, int d, String s) {
0883: gen(a);
0884: sp();
0885: gen(b);
0886: sp();
0887: gen(c);
0888: sp();
0889: gen(d);
0890: sp();
0891: gen(s);
0892: }
0893:
0894: protected void gencr(String s) {
0895: gen(s);
0896: cr();
0897: }
0898:
0899: protected void gencr(String s, String s2) {
0900: gen(s, s2);
0901: cr();
0902: }
0903:
0904: protected void gencr(int a, String s) {
0905: gen(a, s);
0906: cr();
0907: }
0908:
0909: protected void gencr(int a, String s, String s2) {
0910: gen(a, s, s2);
0911: cr();
0912: }
0913:
0914: protected void gencr(int a, int b, String s, String s2) {
0915: gen(a, b, s, s2);
0916: cr();
0917: }
0918:
0919: protected void gencr(int a, int b, String s) {
0920: gen(a, b, s);
0921: cr();
0922: }
0923:
0924: protected void gencr(int a, int b, int c, String s) {
0925: gen(a, b, c, s);
0926: cr();
0927: }
0928:
0929: protected void get(String s) {
0930: gen(" get");
0931: gen(s);
0932: PO();
0933: PC();
0934: }
0935:
0936: protected void geti(String s) {
0937: gen(" get");
0938: gen(s, "(int index)");
0939: }
0940:
0941: protected void getidx(String s, boolean b) {
0942: if (b)
0943: geti(s);
0944: else
0945: get(s);
0946: }
0947:
0948: protected void cr() {
0949: try {
0950: jw.cr();
0951: } catch (IOException e) {
0952: throw new RuntimeException(e);
0953: }
0954: }
0955:
0956: protected void geneol(String s) {
0957: gen(s);
0958: eol();
0959: }
0960:
0961: protected void PO() {
0962: gen("(");
0963: }
0964:
0965: protected void PC() {
0966: gen(")");
0967: }
0968:
0969: protected void begin() {
0970: try {
0971: jw.begin();
0972: } catch (IOException e) {
0973: throw new RuntimeException(e);
0974: }
0975: }
0976:
0977: protected void end() {
0978: end(true);
0979: };
0980:
0981: protected void end(boolean cr) {
0982: try {
0983: jw.end(cr);
0984: } catch (IOException e) {
0985: throw new RuntimeException(e);
0986: }
0987: }
0988:
0989: protected void comment() {
0990: gencr("//");
0991: }
0992:
0993: protected void gencrNoI18N(String s) {
0994: gen(s);
0995: noI18N();
0996: }
0997:
0998: protected void gencrNoI18N(String s, String s2) {
0999: gen(s);
1000: gen(s2);
1001: noI18N();
1002: }
1003:
1004: protected void beginNoI18N() {
1005: gencr("// BEGIN" + "_NOI18N");
1006: }
1007:
1008: protected void endNoI18N() {
1009: gencr("// END" + "_NOI18N");
1010: }
1011:
1012: protected void noI18N() {
1013: try {
1014: jw.noI18N();
1015: } catch (IOException e) {
1016: throw new RuntimeException(e);
1017: }
1018: }
1019:
1020: protected void comment(String s) {
1021: try {
1022: jw.comment(s);
1023: } catch (IOException e) {
1024: throw new RuntimeException(e);
1025: }
1026: }
1027:
1028: protected void comment(String s, String s2) {
1029: comment(s + s2);
1030: }
1031:
1032: protected void eol() {
1033: try {
1034: jw.eol();
1035: } catch (IOException e) {
1036: throw new RuntimeException(e);
1037: }
1038: }
1039:
1040: protected void eol(boolean cr) {
1041: gen(";");
1042: if (cr)
1043: cr();
1044: }
1045:
1046: protected void eolNoI18N() {
1047: try {
1048: jw.eolNoI18N();
1049: } catch (IOException e) {
1050: throw new RuntimeException(e);
1051: }
1052: }
1053:
1054: protected void sp() {
1055: gen(" ");
1056: }
1057:
1058: protected void genforprop() {
1059: gencr("for (int i=0; i<this.prop.length; i++)");
1060: }
1061:
1062: protected void gengetprop() {
1063: gencr("BeanProp p = this.beanProp();");
1064: gencr("if (p != null)");
1065: }
1066:
1067: protected void gengetpropbyname() {
1068: gencr("BeanProp p = this.beanProp(n);");
1069: gencr("if (p != null)");
1070: }
1071:
1072: protected void gensig1(String s) {
1073: gen("(", s, " l)");
1074: cr();
1075: }
1076:
1077: protected void gensig2(String s) {
1078: gen("(String n, ", s, " l)");
1079: cr();
1080: }
1081:
1082: protected void tabIn() {
1083: jw.indentOneLevel();
1084: }
1085:
1086: protected void gentab(int n) {
1087: for (int i = 0; i < n; i++)
1088: tabIn();
1089: }
1090:
1091: protected void genSetValue(boolean isScalar, String classType) {
1092: gen(JavaUtil.toObject("value", classType, config.isForME()));
1093: gen(")");
1094: }
1095:
1096: protected void genSetValP(boolean b, String s1, String s2) {
1097: if (b)
1098: gen(s1);
1099: else
1100: gen(s2);
1101: gen(" value");
1102: }
1103:
1104: /**
1105: * This method is called by the BeanBuilder to register a new property
1106: * on this bean class.
1107: */
1108: public Property addProperty(String name, String dtdName,
1109: String namespace, GraphNode node, GraphLink l,
1110: String classType, int nestedLevel, int eltInstance,
1111: int groupInstance, int type, boolean ored,
1112: AttrProp[] propAttributes, String constName,
1113: String defaultValue, boolean directChild, List extraData,
1114: boolean isUnion) {
1115: if (config.isTraceGen()) {
1116: config.messageOut
1117: .println("AbstractCodeGen.addProperty: name="
1118: + name + " dtdName=" + dtdName
1119: + " classType=" + classType + " type="
1120: + type + " eltInstance=" + eltInstance
1121: + " groupInstance=" + groupInstance
1122: + " isUnion=" + isUnion);
1123: /*
1124: if (propAttributes != null)
1125: for (int i = 0; i < propAttributes.length; ++i)
1126: System.out.println(" propAttributes["+i+"]="+propAttributes[i]);
1127: */
1128: }
1129: Property attr = new Property(name, dtdName, namespace, node, l,
1130: classType, eltInstance, groupInstance, nestedLevel,
1131: type, ored, propAttributes, constName, defaultValue,
1132: directChild, extraData, isUnion);
1133: attrList.add(attr);
1134: return attr;
1135: }
1136:
1137: public List/*<AbstractCodeGeneratorClass.Property>*/getPropertyList() {
1138: return attrList;
1139: }
1140:
1141: /**
1142: * Generate the java code in the out stream, using the optional
1143: * metaDD bean graph.
1144: */
1145: public void generate(String filename, MetaDD mdd)
1146: throws IOException {
1147: this .mdd = mdd;
1148: if (className == null)
1149: throw new NullPointerException();
1150: metaElement = getMetaElement(beanElement);
1151:
1152: if (metaElement != null && metaElement.isSkipGeneration()) {
1153: config.messageOut.println("Skipping generation of class "
1154: + filename + " (as specified in the mdd file)"); // NOI18N
1155: return;
1156: }
1157:
1158: config.messageOut.println("Generating class " + filename); // NOI18N
1159: OutputStream out = new FileOutputStream(filename);
1160: generate(out, mdd);
1161: out.close();
1162: }
1163:
1164: public abstract void generate(OutputStream out, MetaDD mdd)
1165: throws IOException;
1166:
1167: protected MetaElement getMetaElement(BeanBuilder.BeanElement be) {
1168: return getMetaElement(be.getDTDName(), be.getNamespace());
1169: }
1170:
1171: protected MetaElement getMetaElement(Property prop) {
1172: BeanBuilder.BeanElement be = prop.getBeanElement();
1173: if (be != null)
1174: return getMetaElement(be);
1175: return getMetaElement(prop.getDTDName(), prop.getNamespace());
1176: }
1177:
1178: protected MetaElement getMetaElement(String dtdName,
1179: String namespace) {
1180: if (mdd == null)
1181: return null;
1182: int size = mdd.sizeMetaElement();
1183: for (int i = 0; i < size; i++) {
1184: MetaElement e = mdd.getMetaElement(i);
1185: if (e == null)
1186: continue;
1187: if (namespace != null
1188: && !namespace.equals(e.getNamespace()))
1189: continue;
1190: if (e.getDtdName().equals(dtdName))
1191: return e;
1192: }
1193: return null;
1194: }
1195:
1196: protected MetaProperty getMetaProperty(Property prop) {
1197: return getMetaProperty(prop.name);
1198: }
1199:
1200: // Return the meta property from the current meta element
1201: protected MetaProperty getMetaProperty(String name) {
1202: MetaProperty ret = null;
1203: // Get the extra information we might have about this bean
1204: if (metaElement != null) {
1205: MetaProperty[] mp = this .metaElement.getMetaProperty();
1206: for (int i = 0; i < mp.length; i++) {
1207: if (mp[i] != null && mp[i].getBeanName().equals(name)) {
1208: ret = mp[i];
1209: break;
1210: }
1211: }
1212: }
1213: return ret;
1214: }
1215:
1216: /**
1217: * Send the schema to the current output channel.
1218: */
1219: protected void printSchema() throws IOException {
1220: if (config.getFilename() == null)
1221: return;
1222: File f = config.getFilename();
1223: if (f.length() < 16384L) {
1224: FileInputStream fi = new FileInputStream(f);
1225: byte[] r = new byte[(int) f.length()];
1226: fi.read(r);
1227: cr();
1228: gencr("/*");
1229: gentab(2);
1230: gencr("The following schema file has been used for generation:");
1231: cr();
1232: gen(new String(r));
1233: fi.close();
1234: cr();
1235: gencr("*/");
1236: }
1237: }
1238:
1239: protected void printComment(String indent) throws IOException {
1240: String comment = (String) beanElement.node
1241: .getExtendedProperty("comment");
1242: if (comment == null)
1243: return;
1244: gen(indent);
1245: gencr("===============================================================");
1246: gen(indent);
1247: // need to escape any special chars
1248: int length = comment.length();
1249: for (int i = 0; i < length; ++i) {
1250: char c = comment.charAt(i);
1251: if (c == '\n') {
1252: cr();
1253: gen(indent);
1254: } else if (c == '*' && i + 1 < length
1255: && comment.charAt(i + 1) == '/') {
1256: jw.write("* /");
1257: ++i;
1258: } else {
1259: jw.write(c);
1260: }
1261: }
1262: cr();
1263: gen(indent);
1264: gencr("===============================================================");
1265: }
1266:
1267: public void dumpBeanTree(java.io.Writer out, String indent,
1268: String indentBy) throws java.io.IOException {
1269: out.write(indent);
1270: out.write(java.beans.Introspector.decapitalize(Common
1271: .convertName(beanElement.node.getName())));
1272: out.write(" <");
1273: out.write(beanElement.node.getName());
1274: out.write(">");
1275: out.write(" : ");
1276: out.write(className);
1277: if (!beanElement.node.getExtraData().isEmpty()) {
1278: out.write(" \t");
1279: out.write(beanElement.node.getExtraData().toString());
1280: }
1281: out.write("\n");
1282: StringBuffer str = new StringBuffer();
1283: int lineCount = 1;
1284: lineCount = dumpAttributes(beanElement.getGraphNode(), str,
1285: indent + indentBy, lineCount);
1286: lineCount = dumpBeanTree(beanElement, str, indent + indentBy,
1287: indentBy, lineCount);
1288: out.write(str.toString());
1289: if (lineCount >= MAX_DUMP_TREE_LINE_COUNT) {
1290: out.write(indent);
1291: out.write("... etc ...\n");
1292: }
1293: }
1294:
1295: protected int dumpBeanTree(BeanBuilder.BeanElement be,
1296: StringBuffer str, String indent, String indentBy,
1297: int lineCount) {
1298: lineCount = beanTree(be.getGraphNode().getGraphLink(), str,
1299: indent, indentBy, lineCount);
1300: if (be.getExtension() != null) {
1301: //lineCount = dumpAttributes(be.getExtension().getGraphNode(), str, indent, lineCount);
1302: lineCount = dumpBeanTree(be.getExtension(), str, indent,
1303: indentBy, lineCount);
1304: }
1305: return lineCount;
1306: }
1307:
1308: protected int dumpAttributes(GraphNode elt, StringBuffer str,
1309: String indent, int lineCount) {
1310: AttrProp[] attrList = elt.getAttributes();
1311:
1312: for (int i = 0; i < attrList.length; i++) {
1313: AttrProp attr = attrList[i];
1314: str.append(indent + "[attr: " + attr + "]");
1315: if (!attr.getExtraData().isEmpty()) {
1316: str.append(" \t");
1317: str.append(attr.getExtraData().toString());
1318: }
1319: str.append("\n");
1320: ++lineCount;
1321: }
1322: if (false && elt.getExtension() != null)
1323: lineCount = dumpAttributes(elt.getExtension(), str, indent,
1324: lineCount);
1325: return lineCount;
1326: }
1327:
1328: protected int beanTree(GraphLink l, StringBuffer str,
1329: String indent, String indentBy, int lineCount) {
1330: if (lineCount >= MAX_DUMP_TREE_LINE_COUNT)
1331: return lineCount; // Enough, already.
1332: for (; l != null; l = l.getSibling()) {
1333: //str.append("l="+l+"\n");
1334: //str.append("l.object="+l.getObject()+"\n");
1335: //str.append("l.lastInGroup="+l.getLastInGroup()+"\n");
1336: String nextIndent = indent + indentBy;
1337: if (l.element != null) {
1338: BeanBuilder.BeanElement be = (BeanBuilder.BeanElement) l.element
1339: .getObject();
1340:
1341: if (be == null)
1342: continue;
1343: Property prop = (Property) l.getObject();
1344: String type = be.getClassType();
1345: String name = l.name;
1346: if ("#PCDATA".equals(l.name) && "String".equals(type))
1347: continue;
1348: if (prop != null) {
1349: type = prop.getType();
1350: if ("EMPTY".equals(prop.dtdName))
1351: name = prop.dtdName;
1352: else
1353: name = prop.beanIntrospectorName() + " <"
1354: + prop.dtdName + ">";
1355: }
1356:
1357: str.append(indent);
1358: str.append(name);
1359: str.append(" : ");
1360: str.append(type);
1361: str.append(TreeBuilder.instanceToString(l
1362: .getElementInstance(), true));
1363: if (l.element.getMarked())
1364: str.append("...");
1365: if (!l.extraData.isEmpty()) {
1366: str.append(" \t");
1367: str.append(l.extraData.toString());
1368: }
1369: if (!be.node.getExtraData().isEmpty()) {
1370: str.append(" \t");
1371: str.append(be.node.getExtraData().toString());
1372: }
1373: str.append("\n");
1374: ++lineCount;
1375:
1376: if (config.isRespectExtension()
1377: && be.getExtension() != null)
1378: lineCount = dumpBeanTree(be.getExtension(), str,
1379: nextIndent, indentBy, lineCount);
1380:
1381: lineCount = this .dumpAttributes(l.element, str,
1382: nextIndent, lineCount);
1383:
1384: if (l.element.getGraphLink() != null) {
1385: if (l.element.getMarked() == false) {
1386: l.element.setMarked(true);
1387: lineCount = beanTree(
1388: l.element.getGraphLink(),
1389: str,
1390: nextIndent
1391: + TreeBuilder.instanceToString(
1392: l.getGroupInstance(),
1393: true)
1394: + (l.isSequenceOr() ? "| " : ""),
1395: indentBy, lineCount);
1396: l.element.setMarked(false);
1397: }
1398: }
1399: }
1400:
1401: String groupInstance = TreeBuilder.instanceToString(l
1402: .getGroupInstance(), true);
1403: if (!"".equals(groupInstance)) {
1404: str.append(indent);
1405: str.append("(\n");
1406: ++lineCount;
1407: }
1408: if (l.getFirstChild() != null) {
1409: lineCount = beanTree(l.getFirstChild(), str, indent
1410: + (("".equals(groupInstance)) ? "" : " ")
1411: + (l.isSequenceOr() ? "| " : ""), indentBy,
1412: lineCount);
1413: }
1414: if (!"".equals(groupInstance)) {
1415: str.append(indent);
1416: str.append(")");
1417: str.append(groupInstance);
1418: str.append("\n");
1419: ++lineCount;
1420: }
1421: }
1422: return lineCount;
1423: }
1424:
1425: public String toString() {
1426: if (packageName == null)
1427: return "Class " + className;
1428: else
1429: return "Class " + packageName + "." + className;
1430: }
1431:
1432: protected void gen(Signature sig) throws IOException {
1433: sig.writeMethod(jw);
1434: }
1435:
1436: public static final int MAX_DUMP_TREE_LINE_COUNT = 512;
1437:
1438: protected static final Signature.TypeOfMethod SETTER = Signature.TypeOfMethod.SETTER;
1439: protected static final Signature.TypeOfMethod SETTERINDEXED = Signature.TypeOfMethod.SETTERINDEXED;
1440: protected static final Signature.TypeOfMethod GETTER = Signature.TypeOfMethod.GETTER;
1441: protected static final Signature.TypeOfMethod GETTERLIST = Signature.TypeOfMethod.GETTERLIST;
1442: protected static final Signature.TypeOfMethod GETTERINDEXED = Signature.TypeOfMethod.GETTERINDEXED;
1443: protected static final Signature.TypeOfMethod SIZE = Signature.TypeOfMethod.SIZE;
1444: protected static final Signature.TypeOfMethod ADD = Signature.TypeOfMethod.ADD;
1445: protected static final Signature.TypeOfMethod REMOVE = Signature.TypeOfMethod.REMOVE;
1446: protected static final Signature.TypeOfMethod OTHER = Signature.TypeOfMethod.OTHER;
1447:
1448: protected static class Signature {
1449: public static class TypeOfMethod {
1450: private final String name;
1451:
1452: private TypeOfMethod(String name) {
1453: this .name = name;
1454: }
1455:
1456: public String toString() {
1457: return "TypeOfMethod " + name;
1458: }
1459:
1460: public static final TypeOfMethod SETTER = new TypeOfMethod(
1461: "setter");
1462: public static final TypeOfMethod SETTERINDEXED = new TypeOfMethod(
1463: "setterindexed");
1464: public static final TypeOfMethod GETTER = new TypeOfMethod(
1465: "getter");
1466: public static final TypeOfMethod GETTERLIST = new TypeOfMethod(
1467: "getterlist");
1468: public static final TypeOfMethod GETTERINDEXED = new TypeOfMethod(
1469: "getterindexed");
1470: public static final TypeOfMethod SIZE = new TypeOfMethod(
1471: "size");
1472: public static final TypeOfMethod ADD = new TypeOfMethod(
1473: "add");
1474: public static final TypeOfMethod REMOVE = new TypeOfMethod(
1475: "remove");
1476: public static final TypeOfMethod OTHER = new TypeOfMethod(
1477: "other");
1478: }
1479:
1480: private String returnType;
1481: private String methodName;
1482: private TypeOfMethod methodType;
1483: private List parameterTypes;
1484: private List parameterNames;
1485: private List throwTypes;
1486: private boolean _isStatic;
1487:
1488: public Signature(String returnType, String methodName,
1489: TypeOfMethod methodType) {
1490: this .returnType = returnType;
1491: this .methodName = methodName;
1492: this .methodType = methodType;
1493: this .parameterTypes = new LinkedList();
1494: this .parameterNames = new LinkedList();
1495: this .throwTypes = new LinkedList();
1496: this ._isStatic = false;
1497: }
1498:
1499: public Signature(String returnType, String methodName) {
1500: this .returnType = returnType;
1501: this .methodName = methodName;
1502: this .methodType = OTHER;
1503: this .parameterTypes = new LinkedList();
1504: this .parameterNames = new LinkedList();
1505: this .throwTypes = new LinkedList();
1506: this ._isStatic = false;
1507: }
1508:
1509: public String getMethodName() {
1510: return methodName;
1511: }
1512:
1513: public String getReturnType() {
1514: return returnType;
1515: }
1516:
1517: public TypeOfMethod getMethodType() {
1518: return methodType;
1519: }
1520:
1521: public boolean isStatic() {
1522: return _isStatic;
1523: }
1524:
1525: public void setStatic() {
1526: _isStatic = true;
1527: }
1528:
1529: public boolean isVoidReturnType() {
1530: return "void".equals(returnType);
1531: }
1532:
1533: public void addParameter(String type, String name) {
1534: parameterTypes.add(type);
1535: parameterNames.add(name);
1536: }
1537:
1538: public void addThrows(String type) {
1539: throwTypes.add(type);
1540: }
1541:
1542: public void writeMethod(JavaWriter jw) throws IOException {
1543: StringBuffer parameters = new StringBuffer();
1544: Iterator itTypes = parameterTypes.iterator();
1545: Iterator itNames = parameterNames.iterator();
1546: boolean first = true;
1547: while (itTypes.hasNext() && itNames.hasNext()) {
1548: if (first)
1549: first = false;
1550: else
1551: parameters.append(", ");
1552: parameters.append((String) itTypes.next());
1553: parameters.append(" ");
1554: parameters.append((String) itNames.next());
1555: }
1556: String exceptions = null;
1557: Iterator itThrows = throwTypes.iterator();
1558: if (itThrows.hasNext()) {
1559: exceptions = "";
1560: first = true;
1561: do {
1562: if (first)
1563: first = false;
1564: else
1565: exceptions += ", ";
1566: exceptions += ((String) itThrows.next());
1567: } while (itThrows.hasNext());
1568: }
1569: int options = jw.PUBLIC | jw.BEANINFO;
1570: if (_isStatic)
1571: options |= jw.STATIC;
1572: jw.writeMethod(methodName, parameters.toString(),
1573: exceptions, returnType, options);
1574: }
1575:
1576: /**
1577: * int sizeFoo()
1578: * int addFoo(Foo value)
1579: */
1580: public String toString() {
1581: StringBuffer str = new StringBuffer();
1582: if (_isStatic)
1583: str.append("static ");
1584: str.append(returnType);
1585: str.append(" ");
1586: str.append(methodName);
1587: str.append("(");
1588: Iterator itTypes = parameterTypes.iterator();
1589: Iterator itNames = parameterNames.iterator();
1590: boolean first = true;
1591: while (itTypes.hasNext() && itNames.hasNext()) {
1592: if (first)
1593: first = false;
1594: else
1595: str.append(", ");
1596: str.append((String) itTypes.next());
1597: str.append(" ");
1598: str.append((String) itNames.next());
1599: }
1600: str.append(")");
1601: Iterator itThrows = throwTypes.iterator();
1602: if (itThrows.hasNext()) {
1603: str.append(" throws ");
1604: first = true;
1605: do {
1606: if (first)
1607: first = false;
1608: else
1609: str.append(", ");
1610: str.append((String) itThrows.next());
1611: } while (itThrows.hasNext());
1612: }
1613: return str.toString();
1614: }
1615:
1616: /**
1617: * Generate what's needed to call the method.
1618: * sizeFoo()
1619: * addFoo(value)
1620: */
1621: public String callMethod() {
1622: StringBuffer str = new StringBuffer();
1623: str.append(methodName);
1624: str.append("(");
1625: Iterator itTypes = parameterTypes.iterator();
1626: Iterator itNames = parameterNames.iterator();
1627: boolean first = true;
1628: while (itTypes.hasNext() && itNames.hasNext()) {
1629: if (first)
1630: first = false;
1631: else
1632: str.append(", ");
1633: str.append((String) itNames.next());
1634: }
1635: str.append(")");
1636: return str.toString();
1637: }
1638: }
1639:
1640: protected static class Signatures {
1641: Map signatureTable;
1642: List others;
1643:
1644: public Signatures() {
1645: signatureTable = new HashMap();
1646: others = new LinkedList();
1647: }
1648:
1649: public void add(Signature sig) {
1650: if (sig.getMethodType() == OTHER)
1651: others.add(sig);
1652: else
1653: signatureTable.put(sig.getMethodType(), sig);
1654: }
1655:
1656: public Signature findSignature(Signature.TypeOfMethod methodType) {
1657: Signature sig = null;
1658: if (methodType == OTHER) {
1659: Iterator it = others.iterator();
1660: if (it.hasNext())
1661: sig = (Signature) it.next();
1662: } else
1663: sig = (Signature) signatureTable.get(methodType);
1664: if (sig == null)
1665: throw new IllegalStateException("Unable to find "
1666: + methodType);
1667: return sig;
1668: }
1669:
1670: public Iterator iterator() {
1671: return new SignaturesIterator();
1672: //return signatureTable.values().iterator();
1673: }
1674:
1675: public class SignaturesIterator implements Iterator {
1676: Iterator tableIterator;
1677: Iterator othersIterator;
1678:
1679: public SignaturesIterator() {
1680: tableIterator = signatureTable.values().iterator();
1681: othersIterator = others.iterator();
1682: }
1683:
1684: public boolean hasNext() {
1685: if (tableIterator.hasNext())
1686: return true;
1687: return othersIterator.hasNext();
1688: }
1689:
1690: public Object next() {
1691: if (tableIterator.hasNext())
1692: return tableIterator.next();
1693: return othersIterator.next();
1694: }
1695:
1696: public void remove() {
1697: throw new UnsupportedOperationException();
1698: }
1699: }
1700: }
1701:
1702: protected Signatures getSignatures(Property a) {
1703: Signatures result = new Signatures();
1704: Signature sig;
1705:
1706: boolean indexed = a.isIndexed();
1707: boolean isScalar = a.isScalar();
1708: String type = getTypeFullClassName(a);
1709: String typeVariable = "value";
1710: //System.out.println("a.name="+a.name+" a.dtdName="+a.dtdName+" a.type="+a.getType());
1711: if (a.isBean && config.isUseInterfaces()) {
1712: MetaElement me = getMetaElement(a);
1713: if (me != null) {
1714: String firstInterface = firstInCommaSeparatedList(me
1715: .getImplements());
1716: if (firstInterface != null
1717: && !firstInterface.equals(config
1718: .getGenerateCommonInterface())
1719: && !firstInterface.equals(packageName + "."
1720: + config.getGenerateCommonInterface())) {
1721: type = firstInterface;
1722: typeVariable = "valueInterface";
1723: a.setPropertyInterface(firstInterface);
1724: }
1725: }
1726: }
1727: String baseType = type;
1728: if (indexed)
1729: type = baseType + "[]";
1730:
1731: // the setter
1732: sig = new Signature("void", "set" + a.name, SETTER);
1733: sig.addParameter(type, typeVariable);
1734: if (config.isVetoable())
1735: sig.addThrows("java.beans.PropertyVetoException");
1736: result.add(sig);
1737: if (indexed) {
1738: sig = new Signature("void", "set" + a.name, SETTERINDEXED);
1739: sig.addParameter("int", "index");
1740: sig.addParameter(baseType, typeVariable);
1741: if (config.isVetoable())
1742: sig.addThrows("java.beans.PropertyVetoException");
1743: result.add(sig);
1744: }
1745:
1746: // the getter
1747: String getterName = a.getReadMethod(false);
1748: result.add(new Signature(type, getterName, GETTER));
1749: if (indexed) {
1750: String returnType = "java.util.List";
1751: if (config.jdkTarget >= 150)
1752: returnType += "<" + JavaUtil.toObjectType(baseType)
1753: + ">";
1754: result.add(new Signature(returnType, "fetch" + a.name
1755: + "List", GETTERLIST));
1756: sig = new Signature(baseType, a.getReadMethod(true),
1757: GETTERINDEXED);
1758: sig.addParameter("int", "index");
1759: result.add(sig);
1760: result.add(new Signature("int", "size" + a.name, SIZE));
1761: sig = new Signature("int", "add" + a.name, ADD);
1762: sig.addParameter(baseType, typeVariable);
1763: if (config.isVetoable())
1764: sig.addThrows("java.beans.PropertyVetoException");
1765: result.add(sig);
1766: sig = new Signature("int", "remove" + a.name, REMOVE);
1767: sig.addParameter(baseType, typeVariable);
1768: if (config.isVetoable())
1769: sig.addThrows("java.beans.PropertyVetoException");
1770: result.add(sig);
1771: }
1772:
1773: return result;
1774: }
1775:
1776: public void generateDelegator(OutputStream out, MetaDD mdd,
1777: String delegatorClassName, String delegatorPackageName)
1778: throws IOException {
1779: Collection generatedMethods = jw.getStoredMethods();
1780: resetGenBuffers();
1781:
1782: select(HEADER_SECTION);
1783: jw.bigComment("Delegate for " + className + "\n\n@"
1784: + Common.GENERATED_TAG);
1785: jw.cr();
1786: if (delegatorPackageName != null) {
1787: jw.writePackage(delegatorPackageName);
1788: cr();
1789: }
1790: gen(PUBLIC, CLASS, delegatorClassName);
1791: if (metaElement.getDelegatorExtends() != null) {
1792: jw.write(" extends ");
1793: jw.write(metaElement.getDelegatorExtends());
1794: }
1795: if (config.getGenerateCommonInterface() != null) {
1796: jw.write(" implements ");
1797: jw.write(config.getGenerateCommonInterface());
1798: }
1799: sp();
1800: begin();
1801:
1802: select(DECL_SECTION);
1803: String delegator = "_" + className; // NOI18N
1804: gen(PROTECTED, fullClassName, delegator);
1805: eol();
1806: cr();
1807:
1808: generateDelegatorConstructors(delegatorClassName);
1809:
1810: List sortedMethods = new LinkedList(generatedMethods);
1811: Collections.sort(sortedMethods);
1812: for (Iterator it = sortedMethods.iterator(); it.hasNext();) {
1813: JavaWriter.Method method = (JavaWriter.Method) it.next();
1814: if (method.isPublic())
1815: generateDelegator(method, delegatorClassName);
1816: }
1817:
1818: select(TRAILER_SECTION);
1819: end();
1820:
1821: printGenBuffers(out);
1822: }
1823:
1824: protected void generateDelegatorConstructors(
1825: String delegatorClassName) throws IOException {
1826: select(CONSTRUCTOR_SECTION);
1827: String delegator = "_" + className; // NOI18N
1828: gen(PUBLIC, delegatorClassName);
1829: PO();
1830: gen(fullClassName);
1831: gen(" delegator");
1832: PC();
1833: sp();
1834: begin();
1835: geneol(delegator + " = delegator");
1836: end();
1837: cr();
1838: }
1839:
1840: protected void generateDelegator(JavaWriter.Method method,
1841: String delegatorClassName) throws IOException {
1842: if ("".equals(method.getReturnType())) {
1843: if (method.getParameters().indexOf(',') < 0
1844: && (method.getParameters().startsWith(
1845: className + " ") || method.getParameters()
1846: .startsWith(fullClassName + " "))) {
1847: // We already have a constructor with that parameter
1848: return;
1849: }
1850: select(CONSTRUCTOR_SECTION);
1851: String delegator = "_" + className; // NOI18N
1852: jw.write("public ");
1853: jw.write(delegatorClassName);
1854: jw.write("(");
1855: jw.write(method.getParameters());
1856: jw.write(") ");
1857: if (method.getExceptions() != null) {
1858: jw.write("throws ", method.getExceptions(), " ");
1859: }
1860: jw.begin();
1861: jw.write(delegator, " = new ", fullClassName);
1862: jw.write("(");
1863: method.writeParametersNoTypes(jw);
1864: jw.writeEol(")");
1865: jw.end();
1866: jw.cr();
1867: return;
1868: }
1869: select(BODY_SECTION);
1870: boolean returnsDelegation = false;
1871: if (className.equals(method.getReturnType())
1872: || fullClassName.equals(method.getReturnType())) {
1873: returnsDelegation = true;
1874: }
1875: jw.beginMethod(method.getName(), method.getParameters(), method
1876: .getExceptions(),
1877: returnsDelegation ? delegatorClassName : method
1878: .getReturnType(), method.getOptions());
1879: if (!"void".equals(method.getReturnType())) {
1880: gen("return ");
1881: }
1882: if (returnsDelegation)
1883: jw.write("new ", delegatorClassName, "(");
1884: if (!method.isStatic())
1885: jw.write("_", className);
1886: else
1887: jw.write(fullClassName);
1888: jw.write(".");
1889: method.writeCall(jw);
1890: if (returnsDelegation)
1891: jw.write(")");
1892: jw.eol();
1893: jw.end();
1894: jw.cr();
1895: }
1896:
1897: /**
1898: * @param var The name of a variable.
1899: */
1900: protected void genWhiteSpaceRestriction(SchemaRep.WhiteSpace ws,
1901: String var, String type) throws IOException {
1902: if (!("String".equals(type) || "java.lang.String".equals(type)))
1903: return;
1904: if (ws.isPreserve())
1905: return;
1906: if (ws.isReplace()) {
1907: jw.beginIf(var + " != null");
1908: jw
1909: .comment("Whitespace Replace due to whitespace restriction.");
1910: jw.writeEol(var + " = " + var
1911: + ".replace('\\n', ' ').replace('\\t', ' ')");
1912: jw.end();
1913: } else if (ws.isCollapse()) {
1914: jw.beginIf(var + " != null");
1915: jw
1916: .comment("Whitespace Collapse due to whitespace restriction.");
1917: jw
1918: .writeEol(var
1919: + " = "
1920: + var
1921: + ".replace('\\n', ' ').replace('\\t', ' ').trim()");
1922: jw.beginFor("int pos = " + var + ".indexOf(\" \")",
1923: "pos >= 0", "pos = " + var
1924: + ".indexOf(\" \", pos)");
1925: jw.writeEol(var + " = " + var + ".substring(0, pos) + "
1926: + var + ".substring(pos+1, " + var + ".length())");
1927: jw.end();
1928: jw.end();
1929: }
1930: }
1931:
1932: protected void genRethrowExceptions(List exceps) {
1933: for (Iterator it = exceps.iterator(); it.hasNext();) {
1934: gen("catch (");
1935: gen((String) it.next());
1936: gen(" e) ");
1937: begin();
1938: geneol("throw new java.lang.RuntimeException(e)");
1939: end();
1940: }
1941: }
1942:
1943: protected void genValidateProperties() throws IOException {
1944: jw.writeEol("boolean restrictionFailure = false");
1945: jw.writeEol("boolean restrictionPassed = false");
1946: Set requiredPropertySet = new HashSet();
1947: Map requiredProperty = new HashMap();
1948: int size = attrList.size();
1949: for (int i = 0; i < size; i++) {
1950: Property a = (Property) attrList.get(i);
1951: boolean indexed = a.isIndexed();
1952: String attr = a.getReadMethod(false) + "()";
1953: String type = a.getType().intern();
1954: boolean mightBeNull = a.canBeNull();
1955: boolean isPrimitiveType = JavaUtil.isPrimitiveType(type);
1956: String propertyName = a.beanIntrospectorName();
1957: boolean hasDataEnumRestriction = false;
1958: String enumArray = "enumRestriction" + a.name;
1959: //boolean checkOrCount = a.ored && !isPrimitiveType;
1960: boolean checkOrCount = a.ored;
1961: if (checkOrCount) {
1962: //jw.comment("a.groupInstance="+a.getGroupInstance());
1963: // If there can be zero of them, then don't check the or.
1964: if (a.getGroupInstance() == Common.TYPE_0_N
1965: || a.getGroupInstance() == Common.TYPE_0_1) {
1966: checkOrCount = false;
1967: }
1968: }
1969: jw.comment("Validating property " + propertyName);
1970: //jw.writeEol("System.out.println(\"Validating property "+propertyName+"\")");
1971: if (a.isUnion())
1972: jw.writeEol("restrictionPassed = false");
1973: if (a.ored) {
1974: } else {
1975: switch (a.elementInstance & Common.MASK_INSTANCE) {
1976: case Common.TYPE_1:
1977: if (isPrimitiveType) {
1978: // There is always one of them (no null).
1979: break;
1980: }
1981: if (a.isNillable())
1982: break;
1983: genValidateIf(attr + " == null", propertyName,
1984: ValidateException.FailureType.NULL_VALUE,
1985: jw);
1986: break;
1987: case Common.TYPE_0_1:
1988: break;
1989: case Common.TYPE_0_N:
1990: // Never a problem.
1991: break;
1992: case Common.TYPE_1_N:
1993: genValidateIf("size" + a.name + "() == 0",
1994: propertyName,
1995: ValidateException.FailureType.NULL_VALUE,
1996: jw);
1997: break;
1998: }
1999: }
2000: if (indexed && a.isAttribute())
2001: continue;
2002: // Test children
2003: int markedPosition = -1;
2004: if (indexed) {
2005: for (Iterator it = a.extraDataIterator(); it.hasNext();) {
2006: Object extraData = it.next();
2007: if (extraData instanceof DataListRestriction) {
2008: DataListRestriction dlr = (DataListRestriction) extraData;
2009: dlr.genRestriction(jw, "size" + a.name + "()",
2010: a.getReadMethod(false), type,
2011: "restrictionFailure", false);
2012: jw.beginIf("restrictionFailure");
2013: genValidateFail(
2014: JavaUtil.instanceFrom(
2015: "java.lang.String", attr + " "
2016: + dlr.toString()),
2017: propertyName,
2018: false,
2019: ValidateException.FailureType.DATA_RESTRICTION,
2020: jw);
2021: jw.end();
2022: }
2023: }
2024: markedPosition = jw.getCurrentPosition();
2025: jw.beginFor("int _index = 0", "_index < size" + a.name
2026: + "()", "++_index");
2027: jw.write(getTypeFullClassName(a));
2028: jw.write(" element = ");
2029: if (a.getPropertyInterface() != null) {
2030: jw.write("(", getTypeFullClassName(a), ") ");
2031: }
2032: jw.writeEol(a.getReadMethod(true) + "(_index)");
2033: attr = "element";
2034: }
2035: if (mightBeNull) {
2036: if (markedPosition == -1)
2037: markedPosition = jw.getCurrentPosition();
2038: jw.beginIf(attr + " != null");
2039: }
2040:
2041: int marked2Position = jw.getCurrentPosition();
2042: if (a.isBean) {
2043: if (a.getPropertyInterface() == null) {
2044: if (!a.getGraphNode().isCreated()) {
2045: jw.beginTry();
2046: jw
2047: .comment("Catch and deal with any foreign validate exceptions.");
2048: }
2049: jw.writeEol(attr, ".validate()");
2050: if (!a.getGraphNode().isCreated()) {
2051: jw.endCatch("java.lang.Exception e");
2052: jw
2053: .writeEol("throw new java.lang.RuntimeException(e)");
2054: jw.end();
2055: }
2056: } else
2057: jw
2058: .writeEol("((" + type + ")", attr,
2059: ").validate()");
2060: }
2061: genForRestrictions(a, attr);
2062: //System.out.println(" a.name="+a.name);
2063: for (Iterator it = a.extraDataIterator(); it.hasNext();) {
2064: Object extraData = it.next();
2065: //System.out.println(" Found extraData="+extraData);
2066: //jw.comment("name="+a.name+" Found extraData="+extraData);
2067: if (extraData instanceof DataTypeRestriction) {
2068: DataTypeRestriction dtr = (DataTypeRestriction) extraData;
2069: dtr.genRestriction(jw, attr, type,
2070: "restrictionFailure", false);
2071: jw.beginIf("restrictionFailure");
2072: genValidateFail(
2073: JavaUtil.instanceFrom("java.lang.String",
2074: attr + " " + dtr.toString()),
2075: propertyName,
2076: false,
2077: ValidateException.FailureType.DATA_RESTRICTION,
2078: jw);
2079: jw.end();
2080: }
2081: }
2082: for (Iterator it = a.extraDataIterator(); it.hasNext();) {
2083: Object extraData = it.next();
2084: if (extraData instanceof DataEnumRestriction) {
2085: DataEnumRestriction der = (DataEnumRestriction) extraData;
2086: if (!hasDataEnumRestriction) {
2087: // first one
2088: hasDataEnumRestriction = true;
2089: jw.write("final " + type + "[] " + enumArray
2090: + " = {");
2091: } else {
2092: jw.write(", ");
2093: }
2094: der.genRestriction(jw, type);
2095: }
2096: }
2097: if (hasDataEnumRestriction) {
2098: jw.writeEol("}");
2099: jw.writeEol("restrictionFailure = true");
2100: jw.beginFor("int _index2 = 0", "_index2 < " + enumArray
2101: + ".length", "++_index2");
2102: jw.beginIf(JavaUtil.genEquals(type, enumArray
2103: + "[_index2]", attr, false));
2104: jw.writeEol("restrictionFailure = false");
2105: jw.writeEol("break");
2106: jw.end();
2107: jw.end();
2108: jw.beginIf("restrictionFailure");
2109: genValidateFail(
2110: JavaUtil.instanceFrom("java.lang.String", attr
2111: + " enumeration test"), propertyName,
2112: false,
2113: ValidateException.FailureType.ENUM_RESTRICTION,
2114: jw);
2115: jw.end();
2116: }
2117:
2118: if (marked2Position != jw.getCurrentPosition()) {
2119: if (mightBeNull) {
2120: jw.end();
2121: }
2122: if (indexed) {
2123: jw.end();
2124: }
2125: } else {
2126: if (markedPosition >= 0) {
2127: // We didn't write anything since marked2Position, which
2128: // means that we didn't need the stuff after markedPosition
2129: jw.truncateAtPosition(markedPosition);
2130: }
2131: if (mightBeNull)
2132: jw.indentLeft();
2133: if (indexed)
2134: jw.indentLeft();
2135: }
2136:
2137: if (checkOrCount) {
2138: GraphLink gl = a.getGraphLink();
2139: //jw.comment("checkOrCount: gl="+gl);
2140: GraphLink parentgl = null;
2141: if (gl != null) {
2142: parentgl = gl.getParent();
2143: }
2144: //if (parentgl == null || parentgl.getGroupInstance() == Common.TYPE_1) {
2145: List requiredPropertyTest = new ArrayList();
2146: jw.beginIf(testIfPropertySet(a));
2147: requiredPropertyTest.add(testIfPropertyNotSet(a));
2148: for (Iterator it = a.getMutuallyExclusiveProperties()
2149: .iterator(); it.hasNext();) {
2150: Property prop = (Property) it.next();
2151: jw.beginIf(testIfPropertySet(prop));
2152: requiredPropertyTest
2153: .add(testIfPropertyNotSet(prop));
2154: genValidateFail(
2155: "mutually exclusive properties: " + a.name
2156: + " and " + prop.name,
2157: prop.name,
2158: true,
2159: ValidateException.FailureType.MUTUALLY_EXCLUSIVE,
2160: jw);
2161: jw.end();
2162: }
2163: jw.end();
2164:
2165: //
2166: // This is preparing for the check that at least 1
2167: // of the properties are set.
2168: // Sort our list of property checks and store the
2169: // if expression into a Set, so that we generate
2170: // only one if per group of properties.
2171: //
2172: Collections.sort(requiredPropertyTest);
2173: StringBuffer requiredExpr = new StringBuffer();
2174: boolean first = true;
2175: for (Iterator it = requiredPropertyTest.iterator(); it
2176: .hasNext();) {
2177: if (first)
2178: first = false;
2179: else
2180: requiredExpr.append(" && ");
2181: requiredExpr.append((String) it.next());
2182: }
2183: String requiredExprString = requiredExpr.toString();
2184: requiredPropertySet.add(requiredExprString);
2185: requiredProperty.put(requiredExprString, a);
2186: }
2187: }
2188: for (Iterator it = requiredPropertySet.iterator(); it.hasNext();) {
2189: String required = (String) it.next();
2190: Property prop = (Property) requiredProperty.get(required);
2191: jw.beginIf(required);
2192: genValidateFail("required properties: " + required,
2193: prop.name, true,
2194: ValidateException.FailureType.NULL_VALUE, jw);
2195: jw.end();
2196: }
2197: }
2198:
2199: protected void genForRestrictions(Property a, String attr)
2200: throws IOException {
2201: boolean isUnion = a.isUnion();
2202: String propertyName = a.beanIntrospectorName();
2203: String enumArray = "enumRestriction" + a.name;
2204: String type = a.getType().intern();
2205: SchemaRep.Restriction restrict = null;
2206: for (Iterator it = a.extraDataIterator(); it.hasNext();) {
2207: boolean hasDataEnumRestriction = false;
2208: Object extraData = it.next();
2209: if (extraData instanceof SchemaRep.Restriction)
2210: restrict = (SchemaRep.Restriction) extraData;
2211: else
2212: continue;
2213: if (isUnion) {
2214: // There is no type associated with the union
2215: // So get the type of the restriction
2216: String tempType = restrict.getJavaTypeName();
2217: if (tempType != null)
2218: type = tempType.intern();
2219: jw.write("{\n");
2220: }
2221: boolean firstPattern = true;
2222: for (Iterator itr = restrict.subElementsIterator(); itr
2223: .hasNext();) {
2224: Object rType = itr.next();
2225: if (rType instanceof SchemaRep.Pattern) {
2226: if (firstPattern) {
2227: jw.write("{\n");
2228: jw.writeEol("boolean patternPassed = false");
2229: firstPattern = false;
2230: }
2231: DataTypeRestriction dtr = (DataTypeRestriction) rType;
2232: dtr.genRestriction(jw, attr, type, "patternPassed",
2233: true);
2234: }
2235: }
2236: if (!firstPattern) {
2237: jw.writeEol("restrictionFailure = !patternPassed");
2238: jw.write("}\n");
2239: if (!isUnion) {
2240: jw.beginIf("restrictionFailure");
2241: genValidateFail(
2242: JavaUtil.instanceFrom("java.lang.String",
2243: attr),
2244: propertyName,
2245: false,
2246: ValidateException.FailureType.DATA_RESTRICTION,
2247: jw);
2248: jw.end();
2249: }
2250: }
2251: for (Iterator itr = restrict.subElementsIterator(); itr
2252: .hasNext();) {
2253: Object rType = itr.next();
2254: if (rType instanceof DataListRestriction) {
2255: DataListRestriction dlr = (DataListRestriction) rType;
2256: dlr.genRestriction(jw, "size" + a.name + "()", a
2257: .getReadMethod(false), type,
2258: "restrictionFailure", false);
2259: if (!isUnion) {
2260: jw.beginIf("restrictionFailure");
2261: genValidateFail(
2262: JavaUtil.instanceFrom(
2263: "java.lang.String", attr + " "
2264: + dlr.toString()),
2265: propertyName,
2266: false,
2267: ValidateException.FailureType.DATA_RESTRICTION,
2268: jw);
2269: jw.end();
2270: }
2271: }
2272: if (rType instanceof DataTypeRestriction
2273: && !(rType instanceof SchemaRep.Pattern)) {
2274: DataTypeRestriction dtr = (DataTypeRestriction) rType;
2275: String typeAttr = attr;
2276: if (isUnion) {
2277: // for an element having a uniontype the getXXX function would return String
2278: // So for the actual validation we need to convert the string to the
2279: // restriction's type so that we can compare
2280: jw.beginTry();
2281: typeAttr = "("
2282: + JavaUtil.genParseText(type, attr)
2283: + ")";
2284: }
2285: dtr.genRestriction(jw, typeAttr, type,
2286: "restrictionFailure", false);
2287: if (isUnion) {
2288: // Catch any exception during the comparison
2289: // An exception will be thrown only for the conversion of the type
2290: // so assume failure if an exception occurs, since comparison did not
2291: // occur
2292: jw.endCatch("Exception e");
2293: jw.writeEol("restrictionFailure = true");
2294: jw.end();
2295: }
2296: if (!isUnion) {
2297: jw.beginIf("restrictionFailure");
2298: genValidateFail(
2299: JavaUtil.instanceFrom(
2300: "java.lang.String", attr + " "
2301: + dtr.toString()),
2302: propertyName,
2303: false,
2304: ValidateException.FailureType.DATA_RESTRICTION,
2305: jw);
2306: jw.end();
2307: }
2308: }
2309: }
2310: for (Iterator itr = restrict.subElementsIterator(); itr
2311: .hasNext();) {
2312: Object rType = itr.next();
2313: if (rType instanceof DataEnumRestriction) {
2314: DataEnumRestriction der = (DataEnumRestriction) rType;
2315: if (!hasDataEnumRestriction) {
2316: // first one
2317: hasDataEnumRestriction = true;
2318: jw.write("final " + type + "[] " + enumArray
2319: + " = {");
2320: } else {
2321: jw.write(", ");
2322: }
2323: der.genRestriction(jw, type);
2324: }
2325: }
2326: if (hasDataEnumRestriction) {
2327: jw.writeEol("}");
2328: jw.writeEol("restrictionFailure = true");
2329: jw.beginFor("int _index2 = 0", "_index2 < " + enumArray
2330: + ".length", "++_index2");
2331: jw.beginIf(JavaUtil.genEquals(type, enumArray
2332: + "[_index2]", attr, false));
2333: jw.writeEol("restrictionFailure = false");
2334: jw.writeEol("break");
2335: jw.end();
2336: jw.end();
2337: if (!isUnion) {
2338: jw.beginIf("restrictionFailure");
2339: genValidateFail(
2340: JavaUtil.instanceFrom("java.lang.String",
2341: attr + " enumeration test"),
2342: propertyName,
2343: false,
2344: ValidateException.FailureType.ENUM_RESTRICTION,
2345: jw);
2346: jw.end();
2347: }
2348: }
2349: if (isUnion) {
2350: // Set restrictionPassed only if it is not already set to true
2351: jw.beginIf("!restrictionPassed");
2352: jw.writeEol("restrictionPassed = !restrictionFailure");
2353: jw.end();
2354: jw.writeEol("restrictionFailure = false");
2355: jw.write("}\n");
2356: }
2357: }
2358: if (isUnion) {
2359: jw.beginIf("!restrictionPassed");
2360: genValidateFail(JavaUtil.instanceFrom("java.lang.String",
2361: attr), propertyName, false,
2362: ValidateException.FailureType.ALL_RESTRICTIONS, jw);
2363: jw.end();
2364: }
2365: }
2366:
2367: protected void genValidateIf(String test, String name,
2368: ValidateException.FailureType ft, JavaWriter out)
2369: throws IOException {
2370: jw.beginIf(test);
2371: genValidateFail(test, name, true, ft, out);
2372: jw.end();
2373: }
2374:
2375: protected abstract void genValidateFail(String detail, String name,
2376: boolean quoteDetail, ValidateException.FailureType ft,
2377: JavaWriter out) throws IOException;
2378:
2379: public Collection getGeneratedMethods() {
2380: return jw.getStoredMethods();
2381: }
2382:
2383: protected void genDefaultsAccessable(Property a) throws IOException {
2384: String type = a.getType();
2385: boolean mustHaveOneInstance = (!a.ored && a.elementInstance == Common.TYPE_1);
2386: if (config.isDefaultsAccessable()
2387: && !a.isIndexed()
2388: && (a.isScalar() || a.getDefaultValue() != null || mustHaveOneInstance)) {
2389: jw.beginMethod("fetchDefault" + a.name, "", null, type,
2390: jw.PUBLIC);
2391: List exceps = JavaUtil.exceptionsFromParsingText(type,
2392: false);
2393: if (!exceps.isEmpty()) {
2394: jw.beginTry();
2395: }
2396: jw.write("return ");
2397: if (a.getDefaultValue() != null)
2398: jw.write(JavaUtil.instanceFrom(type, a
2399: .getDefaultValue()));
2400: else if (config.isMakeDefaults())
2401: jw.write(JavaUtil.genNewDefault(type));
2402: else
2403: jw.write(JavaUtil.nullValueForType(type));
2404: jw.eol();
2405: if (!exceps.isEmpty()) {
2406: end();
2407: genRethrowExceptions(exceps);
2408: }
2409: jw.end();
2410: jw.cr();
2411: }
2412: }
2413:
2414: protected void generateSwitches() throws IOException {
2415: select(jw.BODY_SECTION);
2416: jw
2417: .bigComment("@return true if error, then should display help");
2418: jw.beginMethod("parseArguments", "String[] args", null,
2419: "boolean");
2420: jw.beginFor("int argNum = 0, size = args.length",
2421: "argNum < size", "++argNum");
2422: jw.writeEol("String arg = args[argNum].toLowerCase().intern()");
2423: int size = attrList.size();
2424: Map mandatoryProperties = new LinkedHashMap();
2425: StringBuffer helpParams = new StringBuffer();
2426: int lastHelpParamsPos = 0;
2427: StringBuffer helpText = new StringBuffer();
2428: for (int i = 0; i < size; i++) {
2429: Property a = (Property) attrList.get(i);
2430: XMLSchemaParser.SwitchData sd = (XMLSchemaParser.SwitchData) a
2431: .searchExtraData(XMLSchemaParser.SwitchData.class);
2432: if (sd == null)
2433: continue;
2434: if (sd.isMandatory())
2435: mandatoryProperties.put(sd.getName(), a);
2436: String sw = sd.getName();
2437: sw = sw.toLowerCase();
2438: String type = a.getType().intern();
2439: boolean indexed = a.isIndexed();
2440: String writeMethod;
2441: if (indexed)
2442: writeMethod = a.getAddMethod();
2443: else
2444: writeMethod = a.getWriteMethod();
2445: //jw.comment("a.name="+a.name+" sw="+sw+" sd.help="+sd.getHelp()+" mandatory="+sd.isMandatory());
2446: jw.beginIf("arg == "
2447: + JavaUtil.instanceFrom("String", "-" + sw));
2448: boolean isBoolean = (type == "boolean" || type == "Boolean" || type == "java.lang.Boolean");
2449: helpParams.append(" ");
2450: if (!sd.isMandatory())
2451: helpParams.append("[");
2452: helpParams.append("-");
2453: if (isBoolean) {
2454: jw.writeEol(writeMethod + "(true)");
2455: helpParams.append(sd.getName());
2456: } else {
2457: jw.beginIf("argNum+1 >= size");
2458: jw.writeEol("missingArgument(args, arg)");
2459: jw.writeEol("continue");
2460: jw.end();
2461: jw.writeEol(writeMethod
2462: + "("
2463: + JavaUtil.genParseText(type, "args[++argNum]",
2464: config.isForME()) + ")");
2465: helpParams.append(sd.getName());
2466: helpParams.append(" ");
2467: if (type == "java.io.File")
2468: helpParams.append("filename");
2469: else
2470: helpParams.append(a.dtdName);
2471: }
2472: if (!sd.isMandatory())
2473: helpParams.append("]");
2474: jw.writeEol("continue");
2475: jw.end();
2476: helpText.append(" -");
2477: helpText.append(sd.getName());
2478: helpText.append("\t");
2479: if (sd.getHelp() != null) {
2480: helpText.append(sd.getHelp());
2481: } else {
2482: helpText.append(a.name);
2483: }
2484: helpText.append('\n');
2485: if (isBoolean) {
2486: jw.beginIf("arg == "
2487: + JavaUtil.instanceFrom("String", "-no" + sw));
2488: jw.writeEol(writeMethod + "(false)");
2489: jw.writeEol("continue");
2490: jw.end();
2491: helpParams.append(" [-no");
2492: helpParams.append(sd.getName());
2493: helpParams.append("]");
2494: }
2495: if (helpParams.length() - lastHelpParamsPos > 63) {
2496: helpParams.append("\n");
2497: lastHelpParamsPos = helpParams.length();
2498: }
2499: }
2500: jw.beginIf("arg == \"-help\" || arg == \"--help\"");
2501: jw.writeEol("return true");
2502: jw.end();
2503: jw.writeEol("argNum = unknownArgument(args, arg, argNum)");
2504: jw.end();
2505: for (Iterator it = mandatoryProperties.keySet().iterator(); it
2506: .hasNext();) {
2507: String sw = (String) it.next();
2508: Property a = (Property) mandatoryProperties.get(sw);
2509: jw.beginIf(testIfPropertyNotSet(a));
2510: jw.writeEol("missingMandatoryArgument(", JavaUtil
2511: .instanceFrom("java.lang.String", "-" + sw), ")");
2512: jw.end();
2513: }
2514: jw.writeEol("return false");
2515: jw.end();
2516: jw.cr();
2517: jw.beginMethod("unknownArgument",
2518: "String[] args, String arg, int argNum", null, "int",
2519: jw.PROTECTED);
2520: jw
2521: .writeEol("throw new IllegalArgumentException(\"Found unknown argument '\"+arg+\"'\")");
2522: jw.end();
2523: jw.cr();
2524: jw.beginMethod("missingArgument", "String[] args, String arg",
2525: null, "void", jw.PROTECTED);
2526: jw
2527: .writeEol("throw new IllegalArgumentException(\"Not enough arguments. Need 1 more for '\"+arg+\"'\")");
2528: jw.end();
2529: jw.cr();
2530: jw.beginMethod("missingMandatoryArgument", "String arg", null,
2531: "void", jw.PROTECTED);
2532: jw
2533: .writeEol("throw new IllegalArgumentException(\"Missing argument '\"+arg+\"'\")");
2534: jw.end();
2535: jw.cr();
2536: jw.beginMethod("showHelp", "java.io.PrintStream out");
2537: if (helpParams.length() > 0) {
2538: if (lastHelpParamsPos < helpParams.length())
2539: helpParams.append("\n");
2540: jw.writeEol("out.println(", JavaUtil.instanceFrom(
2541: "java.lang.String", helpParams.toString()), ")");
2542: }
2543: if (helpText.length() > 0) {
2544: jw.writeEol("out.print(", JavaUtil.instanceFrom(
2545: "java.lang.String", helpText.toString()), ")");
2546: }
2547: jw.end();
2548: jw.cr();
2549: }
2550:
2551: protected boolean isMutuallyExclusive(Property a) {
2552: return (a.ored && !a.getMutuallyExclusiveProperties().isEmpty());
2553: }
2554:
2555: /**
2556: * Generate commands for resetting the mutually exclusive properties,
2557: * only if isMutuallyExclusive(a) returns true.
2558: */
2559: protected void genResetMutuallyExclusive(Property a, boolean genTest)
2560: throws IOException {
2561: if (isMutuallyExclusive(a)) {
2562: if (genTest) {
2563: if (a.isIndexed()) {
2564: jw.beginIf("value != null && value.length > 0");
2565: } else {
2566: jw.beginIf("value != "
2567: + JavaUtil.nullValueForType(a.getType()));
2568: }
2569: }
2570: jw.comment("It's a mutually exclusive property.");
2571: for (Iterator it = a.getMutuallyExclusiveProperties()
2572: .iterator(); it.hasNext();) {
2573: Property prop = (Property) it.next();
2574: jw.writeEol(prop.getWriteMethod(), "(", prop
2575: .isIndexed() ? "null" : JavaUtil
2576: .nullValueForType(prop.getType()), ")");
2577: }
2578: if (genTest)
2579: jw.end();
2580: }
2581: }
2582:
2583: /**
2584: * All generated beans are at least this type.
2585: */
2586: protected String commonBeanType() {
2587: String cb = "java.lang.Object";
2588: if (config.getGenerateCommonInterface() != null) {
2589: if (packageName == null)
2590: cb = config.getGenerateCommonInterface();
2591: else
2592: cb = packageName + "."
2593: + config.getGenerateCommonInterface();
2594: }
2595: return cb;
2596: }
2597:
2598: protected String parentBeanType() {
2599: if (config.isExtendBaseBean())
2600: return "org.netbeans.modules.schema2beans.BaseBean";
2601: else
2602: return commonBeanType();
2603: }
2604:
2605: /**
2606: * Returns the first element in a command separated list
2607: */
2608: protected static String firstInCommaSeparatedList(String lst) {
2609: if (lst == null)
2610: return null;
2611: int pos = lst.indexOf(',');
2612: if (pos < 0)
2613: return lst;
2614: return lst.substring(0, pos);
2615: }
2616:
2617: protected String genNewMethod(String abstractType,
2618: String concreteType) throws IOException {
2619: return genNewMethod(abstractType, concreteType, concreteType);
2620: }
2621:
2622: /**
2623: * Generate a method that will get a new instance of some type.
2624: * Only 1 method will be generated per abstractType.
2625: * @param abstractType interface name to use as return type, if
2626: * null, then concreteType is used.
2627: * @param concreteType the class to get a new instance of
2628: * @param concreteFullTypeName the full name of the concreteType
2629: */
2630: protected String genNewMethod(String abstractType,
2631: String concreteType, String concreteFullTypeName)
2632: throws IOException {
2633: if (abstractType == null)
2634: abstractType = concreteType;
2635: abstractType = abstractType.trim();
2636: concreteType = concreteType.trim();
2637: String returnType = abstractType;
2638: boolean abstractConcreteSame = abstractType
2639: .equals(concreteType);
2640: if (abstractConcreteSame)
2641: returnType = concreteFullTypeName;
2642: String methodName = (String) generatedNewMethods
2643: .get(abstractType);
2644: if (methodName == null) {
2645: if (abstractType.indexOf('.') >= 0) {
2646: String base = JavaUtil.baseName(abstractType);
2647: if (generatedNewMethods.containsKey(base)) {
2648: methodName = "new"
2649: + (abstractType.replace('.', '_'));
2650: } else {
2651: methodName = "new" + base;
2652: }
2653: } else {
2654: methodName = "new" + abstractType;
2655: }
2656: jw.pushSelect(NEW_METHOD_SECTION);
2657: jw
2658: .bigComment("Create a new bean using it's default constructor.\nThis does not add it to any bean graph.");
2659: jw.beginMethod(methodName, "", null, returnType, jw.PUBLIC
2660: | jw.BEANINFO);
2661: jw.writeEol("return new ", concreteFullTypeName, "()");
2662: jw.endMethod();
2663:
2664: if (hasDeepCopyConstructor()) {
2665: jw
2666: .bigComment("Create a new bean, copying from another one.\nThis does not add it to any bean graph.");
2667: String formalParam = abstractType + " source";
2668: String actualParam;
2669: if (abstractConcreteSame)
2670: actualParam = "source";
2671: else
2672: actualParam = "(" + concreteType + ") source";
2673: if (config.isGenerateParentRefs()) {
2674: formalParam += ", " + parentBeanType() + " parent";
2675: actualParam += ", parent";
2676: }
2677: formalParam += ", boolean justData";
2678: actualParam += ", justData";
2679: jw.beginMethod(methodName, formalParam, null,
2680: returnType, jw.PUBLIC | jw.BEANINFO);
2681: jw.write("return new ", concreteFullTypeName);
2682: jw.writeEol("(", actualParam, ")");
2683: jw.endMethod();
2684: }
2685: jw.popSelect();
2686: generatedNewMethods.put(abstractType, methodName);
2687: }
2688: return methodName;
2689: }
2690:
2691: protected void genNewDefault(Property prop, boolean wantConcreteType)
2692: throws IOException {
2693: String type = prop.getType();
2694: if (prop.isBean) {
2695: String abstractType = prop.getPropertyInterface();
2696: String methodName = genNewMethod(abstractType, type,
2697: getTypeFullClassName(prop));
2698: if (wantConcreteType) {
2699: if (abstractType != null && !type.equals(abstractType))
2700: jw.write("(", type, ") ");
2701: }
2702: jw.write(methodName, "()");
2703: } else {
2704: jw.write(JavaUtil.genNewDefault(type));
2705: }
2706: }
2707:
2708: protected boolean hasDeepCopyConstructor() {
2709: return false;
2710: }
2711:
2712: protected String testIfPropertySet(Property prop) {
2713: if (prop.isIndexed()) {
2714: return "size" + prop.name + "() > 0";
2715: } else {
2716: return prop.getReadMethod(false) + "() != "
2717: + JavaUtil.nullValueForType(prop.getType());
2718: }
2719: }
2720:
2721: protected String testIfPropertyNotSet(Property prop) {
2722: if (prop.isIndexed()) {
2723: return "size" + prop.name + "() == 0";
2724: } else {
2725: return prop.getReadMethod(false) + "() == "
2726: + JavaUtil.nullValueForType(prop.getType());
2727: }
2728: }
2729:
2730: protected int countNumberOfNonAttributeProperties() {
2731: int count = beanElement.getNonAttributePropertyCount();
2732: /*
2733: int count = 0;
2734: for (int i = 0; i < attrList.size(); i++) {
2735: Property prop = (Property)attrList.get(i);
2736: if (prop.isAttribute())
2737: continue;
2738: ++count;
2739: }
2740: */
2741: if (config.isRespectExtension()) {
2742: count += countNumberOfNonAttributePropertiesRecurse(beanElement
2743: .getExtension());
2744: }
2745: return count;
2746: }
2747:
2748: protected int countNumberOfNonAttributePropertiesRecurse(
2749: BeanBuilder.BeanElement be) {
2750: int count = 0;
2751: while (be != null) {
2752: //config.messageOut.println("extensionBE="+be);
2753: count += be.getNonAttributePropertyCount();
2754: be = be.getExtension();
2755: //config.messageOut.println("count="+count);
2756: }
2757: return count;
2758: }
2759:
2760: public void setPrefixGuesser(PrefixGuesser guesser) {
2761: if (guesser == null) {
2762: if (prefixGuesser == null) {
2763: prefixGuesser = new PrefixGuesser() {
2764: public String guessPrefixFromURI(String uri) {
2765: return SchemaRep.guessPrefix(uri);
2766: }
2767: };
2768: }
2769: } else {
2770: prefixGuesser = guesser;
2771: }
2772: }
2773: }
|