Java tutorial
/** * PlasmaSDO License * * This is a community release of PlasmaSDO, a dual-license * Service Data Object (SDO) 2.1 implementation. * This particular copy of the software is released under the * version 2 of the GNU General Public License. PlasmaSDO was developed by * TerraMeta Software, Inc. * * Copyright (c) 2013, TerraMeta Software, Inc. All rights reserved. * * General License information can be found below. * * This distribution may include materials developed by third * parties. For license and attribution notices for these * materials, please refer to the documentation that accompanies * this distribution (see the "Licenses for Third-Party Components" * appendix) or view the online documentation at * <http://plasma-sdo.org/licenses/>. * */ package org.plasma.text.lang3gl.java; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.plasma.common.WordWrap; import org.plasma.config.PlasmaConfig; import org.plasma.provisioning.Class; import org.plasma.provisioning.ClassRef; import org.plasma.provisioning.DataTypeRef; import org.plasma.provisioning.Documentation; import org.plasma.provisioning.EnumerationConstraint; import org.plasma.provisioning.Package; import org.plasma.provisioning.Property; import org.plasma.provisioning.PropertyNameCollisionException; import org.plasma.provisioning.TypeRef; import org.plasma.provisioning.ValueConstraint; import org.plasma.provisioning.adapter.FieldAdapter; import org.plasma.sdo.DataFlavor; import org.plasma.sdo.DataType; import org.plasma.sdo.helper.DataConverter; import org.plasma.text.TextException; import org.plasma.text.lang3gl.Lang3GLContext; import org.plasma.text.lang3gl.ClassNameResolver; public abstract class DefaultFactory { private static Log log = LogFactory.getLog(DefaultFactory.class); protected Lang3GLContext context; protected static final String LINE_SEP = System.getProperty("line.separator"); protected static final String FILE_SEP = System.getProperty("file.separator"); private Map<Character, String> reservedJavaCharToLiteralMap = new HashMap<Character, String>(); @SuppressWarnings("unused") private DefaultFactory() { } public DefaultFactory(Lang3GLContext context) { this.context = context; this.reservedJavaCharToLiteralMap.put(Character.valueOf('+'), "_plus_"); this.reservedJavaCharToLiteralMap.put(Character.valueOf('-'), "_minus_"); this.reservedJavaCharToLiteralMap.put(Character.valueOf('/'), "_div_"); this.reservedJavaCharToLiteralMap.put(Character.valueOf('*'), "_mult_"); this.reservedJavaCharToLiteralMap.put(Character.valueOf('%'), "_mod_"); this.reservedJavaCharToLiteralMap.put(Character.valueOf('('), "_rp_"); this.reservedJavaCharToLiteralMap.put(Character.valueOf(')'), "_lp_"); this.reservedJavaCharToLiteralMap.put(Character.valueOf('('), "_rb_"); this.reservedJavaCharToLiteralMap.put(Character.valueOf(')'), "_lb_"); } public Lang3GLContext getContext() { return this.context; } /** * Returns a 3Gl language specific class name for the given SDO data-type (as * per the SDO Specification 2.10 Section 8.1) where primitive type names or * wrapper type names returned based on the current context. * @see Lang3GLModelContext * @param dataType the SDO datatype * @return the 3Gl language specific type class name. */ public java.lang.Class<?> getTypeClass(DataType dataType) { return getTypeClass(dataType, this.context.usePrimitives()); } /** * Returns a 3Gl language specific class name for the given SDO data-type (as * per the SDO Specification 2.10 Section 8.1) where primitive type names or * wrapper type names returned based on the current context. * @see Lang3GLModelContext * @param dataType the SDO datatype * @param primitives whether to return a primitive type if possible * based on the given SDO datatype * @return the 3Gl language specific type class name. */ public java.lang.Class<?> getTypeClass(DataType dataType, boolean primitives) { if (primitives) return DataConverter.INSTANCE.toPrimitiveJavaClass(dataType); else return DataConverter.INSTANCE.toWrapperJavaClass(dataType); } public String getPrimitiveTypeDefault(DataType dataType) { switch (dataType) { case Boolean: return "false"; case Byte: case Character: case Float: case Double: case Int: case Integer: case Short: case Long: case Decimal: return "0"; default: throw new TextException("unknown primitive type, " + dataType.toString()); } } @Deprecated protected void collectProvisioningClasses(Package pkg, Class clss, Map<String, Class> classMap) { for (Property field : clss.getProperties()) { TypeRef type = field.getType(); if (type instanceof ClassRef) { ClassRef cref = ((ClassRef) type); Class refClass = this.context.findClass(cref); classMap.put(refClass.getUri() + "#" + refClass.getName(), refClass); } } } /** * Collects class names from reference fields within this class and its superclass ancestry. * @param pkg the package * @param clss the Class * @param nameMap the name map */ //FIXME: move to provisioning tool/helper/whatever @Deprecated protected void collectProvisioningClassesDeep(Package pkg, Class clss, Map<String, Class> classMap) { collectProvisioningClasses(pkg, clss, classMap); if (clss.getSuperClasses() != null && clss.getSuperClasses().size() > 0) { for (ClassRef cref : clss.getSuperClasses()) { Class superClass = this.context.findClass(cref); String qualifiedName = cref.getUri() + "#" + cref.getName(); classMap.put(qualifiedName, superClass); Package superClassPackage = this.context.findPackage(cref); // recurse collectProvisioningClassesDeep(superClassPackage, superClass, classMap); } } } //FIXME: move to provisioning tool/helper/whatever @Deprecated protected void collectProvisioningSuperclasses(Package pkg, Class clss, Map<String, Class> classMap) { if (clss.getSuperClasses() != null && clss.getSuperClasses().size() > 0) { for (ClassRef cref : clss.getSuperClasses()) { Class superClass = this.context.findClass(cref); classMap.put(superClass.getUri() + "#" + superClass.getName(), superClass); Package superClassPackage = this.context.findPackage(cref); // recurse collectProvisioningSuperclasses(superClassPackage, superClass, classMap); } } } //FIXME: move to provisioning tool/helper/whatever @Deprecated protected void collectProvisioningFields(Package targetPkg, Class targetClss, Package pkg, Class clss, Map<String, FieldAdapter> fields) { if (clss.getSuperClasses() != null) for (ClassRef cref : clss.getSuperClasses()) { Class sclss = this.context.findClass(cref); Package spkg = this.context.findPackage(cref); collectProvisioningFields(targetPkg, targetClss, spkg, sclss, fields); } for (Property field : clss.getProperties()) { FieldAdapter existing = fields.get(field.getName()); if (existing != null) { if (existing.getFieldClass().getName().equals(clss.getName()) && existing.getFieldClass().getUri().equals(clss.getUri())) { log.warn("Classifier " + targetClss.getUri() + "#" + targetClss.getName() + " inherits multiple identical properties '" + existing.getFieldClass().getUri() + "#" + existing.getFieldClass().getName() + "." + existing.getField().getName() + "'"); continue; } else if (targetClss.getName().equals(clss.getName()) && targetClss.getUri().equals(clss.getUri())) { throw new PropertyNameCollisionException( "Classifier " + clss.getUri() + "#" + clss.getName() + " with property '" + field.getName() + "' inherits an identically named property from classifier " + existing.getFieldClass().getUri() + "#" + existing.getFieldClass().getName()); } else { throw new PropertyNameCollisionException("Classifier " + targetClss.getUri() + "#" + targetClss.getName() + " inherits multiple properties named '" + field.getName() + "' from 2 parent classifiers, " + existing.getFieldClass().getUri() + "#" + existing.getFieldClass().getName() + " and " + clss.getUri() + "#" + clss.getName()); } } FieldAdapter adapter = new FieldAdapter(pkg, clss, field); fields.put(field.getName(), adapter); } } protected String createImportDeclaration(Package pkg, Class clss, String qualifiedname) { StringBuilder buf = new StringBuilder(); buf.append("import "); buf.append(qualifiedname); buf.append(";"); return buf.toString(); } protected String beginBody() { return "{"; } protected String endBody() { return "}"; } protected TypeClassInfo getTypeClassName(TypeRef type) { TypeClassInfo result = null; if (type instanceof DataTypeRef) { DataTypeRef dataTypeRef = (DataTypeRef) type; DataType sdoType = DataType.valueOf(dataTypeRef.getName()); java.lang.Class<?> primitiveTypeClass = getTypeClass(sdoType, true); java.lang.Class<?> wrapperTypeClass = getTypeClass(sdoType, false); result = new TypeClassInfo(dataTypeRef, sdoType, primitiveTypeClass, wrapperTypeClass, this.context.usePrimitives()); } else if (type instanceof ClassRef) { result = new TypeClassInfo((ClassRef) type, this.context.usePrimitives()); } return result; } protected DataFlavor getDataFlavor(DataTypeRef dataTypeRef) { DataType sdoType = DataType.valueOf(dataTypeRef.getName()); return DataFlavor.fromDataType(sdoType); } @Deprecated protected String getTypeClassName(Class clss) { return clss.getName(); } protected String firstToUpperCase(String name) { if (!Character.isUpperCase(name.charAt(0))) { return name.substring(0, 1).toUpperCase() + name.substring(1); } return name; } protected String toEnumLiteralName(String name) { name = toConstantName(name); StringBuilder buf = new StringBuilder(); char[] array = name.toCharArray(); for (int i = 0; i < array.length; i++) { if (i == 0) { if (Character.isDigit(array[i])) buf.append("_"); } buf.append(array[i]); } return buf.toString(); } protected String toConstantName(String name) { name = name.trim(); StringBuilder buf = new StringBuilder(); char[] array = name.toCharArray(); for (int i = 0; i < array.length; i++) { String lit = reservedJavaCharToLiteralMap.get(Character.valueOf(array[i])); if (lit != null) { buf.append(lit.toUpperCase()); continue; } if (i > 0) { if (Character.isLetter(array[i]) && Character.isUpperCase(array[i])) { if (!Character.isUpperCase(array[i - 1])) buf.append("_"); } } if (Character.isLetterOrDigit(array[i])) { buf.append(Character.toUpperCase(array[i])); } else buf.append("_"); } return buf.toString(); } protected String toMethodFieldName(String name) { return firstToUpperCase(name); } protected String indent(int num) { StringBuilder buf = new StringBuilder(); for (int i = 0; i < num; i++) buf.append(this.getContext().getIndentationToken()); return buf.toString(); } protected String newline(int num) { StringBuilder buf = new StringBuilder(); buf.append(LINE_SEP); for (int i = 0; i < num; i++) buf.append(this.getContext().getIndentationToken()); return buf.toString(); } protected boolean hasOnlySingilarFields(Class clss) { if (clss.getProperties() != null) for (Property field : clss.getProperties()) if (field.isMany()) return false; return true; } protected boolean hasOnlySingilarFieldsDeep(Class clss) { if (!hasOnlySingilarFields(clss)) return false; if (clss.getSuperClasses() != null && clss.getSuperClasses().size() > 0) for (ClassRef cref : clss.getSuperClasses()) { Class superClass = this.context.findClass(cref); return hasOnlySingilarFieldsDeep(superClass); } return true; } protected void createSingularGetterDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Returns the value of the <b>"); buf.append(field.getName()); buf.append("</b> property."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { buf.append(newline(1)); buf.append(" * <p></p>"); buf.append(newline(1)); buf.append(" * <b>Property Definition: </b>"); buf.append(definition); } buf.append(newline(1)); buf.append(" * @return the value of the <b>"); buf.append(field.getName()); buf.append("</b> property."); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public "); buf.append(typeClassName.getSimpleName()); buf.append(" get"); buf.append(toMethodFieldName(field.getName())); buf.append("()"); } protected void createSingularSetterDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Sets the value of the <b>"); buf.append(field.getName()); buf.append("</b> property to the given value."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { buf.append(newline(1)); buf.append(" * <p></p>"); buf.append(newline(1)); buf.append(" * <b>Property Definition: </b>"); buf.append(definition); } if (field.getValueConstraint() != null || field.getEnumerationConstraint() != null) { if (field.getValueConstraint() != null) { buf.append(newline(1)); buf.append(" * <p></p>"); buf.append(newline(1)); buf.append(" * <b>Value Constraints: </b>"); buf.append("<pre>"); ValueConstraint vc = field.getValueConstraint(); if (vc.getMinLength() != null) { buf.append(newline(1)); buf.append(" * minLength: "); buf.append(vc.getMinLength()); } if (vc.getMaxLength() != null) { buf.append(newline(1)); buf.append(" * maxLength: "); buf.append(vc.getMaxLength()); } if (vc.getMinInclusive() != null) { buf.append(newline(1)); buf.append(" * minInclusive: "); buf.append(vc.getMinInclusive()); } if (vc.getMaxInclusive() != null) { buf.append(newline(1)); buf.append(" * maxInclusive: "); buf.append(vc.getMaxInclusive()); } if (vc.getMinExclusive() != null) { buf.append(newline(1)); buf.append(" * minExclusive: "); buf.append(vc.getMinExclusive()); } if (vc.getMaxExclusive() != null) { buf.append(newline(1)); buf.append(" * maxExclusive: "); buf.append(vc.getMaxExclusive()); } if (vc.getFractionDigits() != null) { buf.append(newline(1)); buf.append(" * fractionDigits: "); buf.append(vc.getFractionDigits()); } if (vc.getTotalDigits() != null) { buf.append(newline(1)); buf.append(" * totalDigits: "); buf.append(vc.getTotalDigits()); } if (vc.getPattern() != null) { buf.append(newline(1)); buf.append(" * pattern: "); buf.append(vc.getPattern()); } buf.append("</pre>"); } else if (field.getEnumerationConstraint() != null) { buf.append(newline(1)); buf.append(" * <p></p>"); buf.append(newline(1)); buf.append(" * <b>Enumeration Constraints: </b>"); buf.append("<pre>"); EnumerationConstraint ec = field.getEnumerationConstraint(); buf.append(newline(1)); buf.append(" * <b>name:</b> "); buf.append(ec.getValue().getName()); buf.append(newline(1)); buf.append(" * <b>URI:</b>"); buf.append(ec.getValue().getUri()); buf.append("</pre>"); } } buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public void set"); buf.append(toMethodFieldName(field.getName())); buf.append("("); buf.append(typeClassName.getSimpleName()); buf.append(" value)"); } protected void createUnsetterDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Unsets the <b>"); buf.append(field.getName()); buf.append("</b> property, "); if (field.isMany()) { buf.append("clearing the underlying collection. "); } else { buf.append("the value"); buf.append(newline(1)); buf.append(" * of the property of the object being set to the property's"); buf.append(newline(1)); buf.append(" * default value. "); } buf.append("The property will no longer be"); buf.append(newline(1)); buf.append(" * considered set."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { addPropertyModelDocLinks(clss, field, typeClassName, buf); } buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public void unset"); buf.append(toMethodFieldName(field.getName())); buf.append("()"); } private void addPropertyModelDocLinks(Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(newline(1)); buf.append(" * <p></p>"); buf.append(newline(1)); buf.append(" * <b>Property Definition: </b>"); buf.append(newline(1)); buf.append(" * See {@link #get"); buf.append(toMethodFieldName(field.getName())); buf.append("() get"); buf.append(toMethodFieldName(field.getName())); buf.append("} or {@link #set"); buf.append(toMethodFieldName(field.getName())); if (!field.isMany()) { buf.append("("); buf.append(typeClassName.getSimpleName()); buf.append(" value) "); } else { buf.append("("); buf.append(typeClassName.getSimpleName()); buf.append("[] value) "); } buf.append("set"); buf.append(toMethodFieldName(field.getName())); buf.append("(...)} for a definition of property <b>"); buf.append(field.getName()); buf.append("</b>"); } protected void createIsSetDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Returns true if the <b>"); buf.append(field.getName()); buf.append("</b> property is set."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { addPropertyModelDocLinks(clss, field, typeClassName, buf); } // return buf.append(newline(1)); buf.append(" * @return true if the <b>"); buf.append(field.getName()); buf.append("</b> property is set."); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public boolean isSet"); buf.append(toMethodFieldName(field.getName())); buf.append("()"); } protected void createCreatorDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Creates and returns a new instance of Type {@link "); buf.append(typeClassName.getSimpleName()); buf.append("} automatically establishing a containment relationship "); buf.append("through the object's reference property, <b>"); buf.append(field.getName()); buf.append("</b>."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { addPropertyModelDocLinks(clss, field, typeClassName, buf); } // return buf.append(newline(1)); buf.append(" * @return a new instance of Type {@link "); buf.append(typeClassName.getSimpleName()); buf.append("} automatically establishing a containment relationship "); buf.append("through the object's reference property <b>"); buf.append(field.getName()); buf.append("</b>."); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public "); buf.append(typeClassName.getSimpleName()); buf.append(" create"); buf.append(toMethodFieldName(field.getName())); buf.append("()"); } protected void createCreatorByAbstractClassDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append( " * Creates and returns a new instance of the given subclass Type for abstract base Type {@link "); buf.append(typeClassName.getSimpleName()); buf.append("} automatically establishing a containment relationship "); buf.append("through the object's reference property, <b>"); buf.append(field.getName()); buf.append("</b>."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { addPropertyModelDocLinks(clss, field, typeClassName, buf); } //params buf.append(newline(1)); buf.append(" * @param clss the subclass Type"); //return buf.append(newline(1)); buf.append(" * Returns a new instance of the given subclass Type for abstract base Type {@link "); buf.append(typeClassName.getSimpleName()); buf.append("}."); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public "); buf.append(typeClassName.getSimpleName()); buf.append(" create"); buf.append(toMethodFieldName(field.getName())); buf.append("(Class<? extends "); buf.append(typeClassName.getSimpleName()); buf.append("> clss)"); } protected void createManyGetterDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Returns an array of <b>"); buf.append(typeClassName.getSimpleName()); buf.append("</b> set for the object's multi-valued property <b>"); buf.append(field.getName()); buf.append("</b>."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { buf.append(newline(1)); buf.append(" * <p></p>"); buf.append(newline(1)); buf.append(" * <b>Property Definition: </b>"); buf.append(definition); } // return buf.append(newline(1)); buf.append(" * @return an array of <b>"); buf.append(typeClassName.getSimpleName()); buf.append("</b> set for the object's multi-valued property <b>"); buf.append(field.getName()); buf.append("</b>."); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public "); buf.append(typeClassName.getSimpleName()); buf.append("[] get"); buf.append(toMethodFieldName(field.getName())); buf.append("()"); } protected void createManyIndexGetterDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Returns the <b>"); buf.append(typeClassName.getSimpleName()); buf.append("</b> set for the object's multi-valued property <b>"); buf.append(field.getName()); buf.append("</b> based on the given index."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { addPropertyModelDocLinks(clss, field, typeClassName, buf); } // params buf.append(newline(1)); buf.append(" * @param idx the index"); // return buf.append(newline(1)); buf.append(" * @return the <b>"); buf.append(typeClassName.getSimpleName()); buf.append("</b> set for the object's multi-valued property <b>"); buf.append(field.getName()); buf.append("</b> based on the given index."); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public "); buf.append(typeClassName.getSimpleName()); buf.append(" get"); buf.append(toMethodFieldName(field.getName())); buf.append("(int idx)"); } protected void createManyCountDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Returns a count for multi-valued property <b>"); buf.append(field.getName()); buf.append("</b>."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { addPropertyModelDocLinks(clss, field, typeClassName, buf); } // return buf.append(newline(1)); buf.append(" * @return a count for multi-valued property <b>"); buf.append(field.getName()); buf.append("</b>."); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public int get"); buf.append(toMethodFieldName(field.getName())); buf.append("Count()"); } protected void createManySetterDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Sets the given array of Type <b>"); buf.append(typeClassName.getSimpleName()); buf.append("</b> for the object's multi-valued property <b>"); buf.append(field.getName()); buf.append("</b>."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { buf.append(newline(1)); buf.append(" * <p></p>"); buf.append(newline(1)); buf.append(" * <b>Property Definition: </b>"); buf.append(definition); } // params buf.append(newline(1)); buf.append(" * @param value the array value"); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public void set"); buf.append(toMethodFieldName(field.getName())); buf.append("("); buf.append(typeClassName.getSimpleName()); buf.append("[] value)"); } protected void createManyAdderDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Adds the given value of Type <b>"); buf.append(typeClassName.getSimpleName()); buf.append("</b> for the object's multi-valued property <b>"); buf.append(field.getName()); buf.append("</b>."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { addPropertyModelDocLinks(clss, field, typeClassName, buf); } // params buf.append(newline(1)); buf.append(" * @param value the value to add"); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public void add"); buf.append(toMethodFieldName(field.getName())); buf.append("("); buf.append(typeClassName.getSimpleName()); buf.append(" value)"); } protected void createManyRemoverDeclaration(Package pkg, Class clss, Property field, TypeClassInfo typeClassName, StringBuilder buf) { buf.append(this.newline(1)); buf.append("/**"); // begin javadoc buf.append(newline(1)); buf.append(" * Removes the given value of Type <b>"); buf.append(typeClassName.getSimpleName()); buf.append("</b> for the object's multi-valued property <b>"); buf.append(field.getName()); buf.append("</b>."); String definition = this.getWrappedDocmentations(field.getDocumentations(), 1); if (definition != null && definition.length() > 0) { addPropertyModelDocLinks(clss, field, typeClassName, buf); } // params buf.append(newline(1)); buf.append(" * @param value the value to remove"); buf.append(newline(1)); buf.append(" */"); // end javadoc buf.append(newline(1)); buf.append("public void remove"); buf.append(toMethodFieldName(field.getName())); buf.append("("); buf.append(typeClassName.getSimpleName()); buf.append(" value)"); } protected void collectReferenceClassNames(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver) { collectReferenceClassNames(pkg, clss, nameMap, resolver, true, -1); } /** * Collects class names from reference fields within this class. * @param pkg the package * @param clss the Class * @param nameMap the name map used to store collected results * @param resolver the qualified name resolver */ protected void collectReferenceClassNames(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver, boolean collectAbstractClasses, int maxLevel) { for (Property field : clss.getProperties()) { TypeRef type = field.getType(); if (type instanceof DataTypeRef) continue; ClassRef ref = ((ClassRef) type); String qualifiedName = resolver.getQualifiedName(ref); nameMap.put(qualifiedName, qualifiedName); } } protected void collectDataClassNames(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver) { collectDataClassNames(pkg, clss, nameMap, resolver, true, -1); } /** * Collects class names from data fields within this class. * @param pkg the package * @param clss the Class * @param nameMap the name map used to store collected results * @param resolver the qualified name resolver */ protected void collectDataClassNames(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver, boolean collectAbstractClasses, int maxLevel) { for (Property field : clss.getProperties()) { TypeRef type = field.getType(); if (type instanceof ClassRef) continue; DataType sdoType = DataType.valueOf(((DataTypeRef) type).getName()); java.lang.Class<?> typeClass = this.getTypeClass(sdoType); if (typeClass.isPrimitive()) continue; if (typeClass.isArray()) continue; nameMap.put(typeClass.getName(), typeClass.getName()); } } protected void collectSuperClassNames(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver) { collectSuperClassNames(pkg, clss, nameMap, resolver, true, -1); } /** * Collects class names from super classes for this class. * @param pkg the package * @param clss the Class * @param nameMap the name map used to store collected results * @param resolver the qualified name resolver */ protected void collectSuperClassNames(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver, boolean collectAbstractClasses, int maxLevel) { if (clss.getSuperClasses() != null && clss.getSuperClasses().size() > 0) { for (ClassRef cref : clss.getSuperClasses()) { Class superClass = this.context.findClass(cref); if (superClass.isAbstract() && !collectAbstractClasses) continue; Package superClassPackage = this.context.findPackage(cref); String qualifiedName = resolver.getQualifiedName(superClass); nameMap.put(qualifiedName, qualifiedName); // recurse collectSuperClassNames(superClassPackage, superClass, nameMap, resolver, collectAbstractClasses, maxLevel); } } } /** * Collects class names from reference fields within this class and its superclass ancestry. * @param pkg the package * @param clss the Class * @param nameMap the name map used to store collected results * @param resolver the qualified name resolver */ protected void collectReferenceFieldClassNamesDeep(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver, boolean collectAbstractClasses, int maxLevel) { collectReferenceClassNames(pkg, clss, nameMap, resolver); if (clss.getSuperClasses() != null && clss.getSuperClasses().size() > 0) { for (ClassRef cref : clss.getSuperClasses()) { Class superClass = this.context.findClass(cref); if (superClass.isAbstract() && !collectAbstractClasses) continue; Package superClassPackage = this.context.findPackage(cref); // recurse collectReferenceFieldClassNamesDeep(superClassPackage, superClass, nameMap, resolver, collectAbstractClasses, maxLevel); } } } /** * Collects class names from reference fields within this class and its superclass ancestry. * @param pkg the package * @param clss the Class * @param nameMap the name map used to store collected results * @param resolver the qualified name resolver */ protected void collectDataFieldClassNamesDeep(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver, boolean collectAbstractClasses, int maxLevel) { collectDataClassNames(pkg, clss, nameMap, resolver); if (clss.getSuperClasses() != null && clss.getSuperClasses().size() > 0) { for (ClassRef cref : clss.getSuperClasses()) { Class superClass = this.context.findClass(cref); if (superClass.isAbstract() && !collectAbstractClasses) continue; // Note: don't map the superclass qualified name - we are collecting data field names hers Package superClassPackage = this.context.findPackage(cref); // recurse collectDataFieldClassNamesDeep(superClassPackage, superClass, nameMap, resolver, collectAbstractClasses, maxLevel); } } } /** * Collects class names from the ancestry of the given class. * @param pkg the package * @param clss the Class * @param nameMap the name map used to store collected results * @param resolver the qualified name resolver */ protected void collectSuperclassNames(Package pkg, Class clss, Map<String, String> nameMap, ClassNameResolver resolver) { if (clss.getSuperClasses() != null && clss.getSuperClasses().size() > 0) { for (ClassRef cref : clss.getSuperClasses()) { String qualifiedName = resolver.getQualifiedName(cref); Class superClass = this.context.findClass(cref); nameMap.put(qualifiedName, qualifiedName); Package superClassPackage = this.context.findPackage(cref); // recurse collectSuperclassNames(superClassPackage, superClass, nameMap, resolver); } } } protected Map<String, String> createFieldImportMap(Package pkg, Class clss, ClassNameResolver resolver) { Map<String, String> nameMap = new TreeMap<String, String>(); collectDataFieldClassNamesDeep(pkg, clss, nameMap, resolver, true, -1); collectReferenceFieldClassNamesDeep(pkg, clss, nameMap, resolver, true, -1); return nameMap; } protected String createImportDeclarations(Map<String, String> nameMap) { StringBuilder buf = new StringBuilder(); for (String name : nameMap.values()) { buf.append(LINE_SEP); buf.append("import "); buf.append(name); buf.append(";"); } return buf.toString(); } protected String getWrappedDocmentations(List<Documentation> docs, int indent) { // add formatted doc from UML or derived default doc StringBuilder docsBuf = new StringBuilder(); if (docs != null) { for (Documentation doc : docs) { if (doc.getBody() == null || doc.getBody().getValue() == null) continue; String docText = doc.getBody().getValue().trim(); if (docText.length() == 0) continue; String wrappedDoc = WordWrap.wordWrap(docText, 60, Locale.ENGLISH); String[] docLines = wrappedDoc.split("\n"); for (String line : docLines) { docsBuf.append(newline(indent)); docsBuf.append(" * "); docsBuf.append(line); } } } return docsBuf.toString(); } }