0001: package xdoclet.modules.ojb;
0002:
0003: /* Copyright 2003-2005 The Apache Software Foundation
0004: *
0005: * Licensed under the Apache License, Version 2.0 (the "License");
0006: * you may not use this file except in compliance with the License.
0007: * You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: import java.util.*;
0019:
0020: import xjavadoc.*;
0021: import xdoclet.XDocletException;
0022: import xdoclet.XDocletTagSupport;
0023: import xdoclet.modules.ojb.constraints.*;
0024: import xdoclet.modules.ojb.model.*;
0025: import xdoclet.util.Translator;
0026: import xdoclet.util.TypeConversionUtil;
0027:
0028: /**
0029: * Provides functions for the XDoclet template.
0030: *
0031: * @author <a href="mailto:tomdz@users.sourceforge.net">Thomas Dudziak (tomdz@users.sourceforge.net)</a>
0032: * @xdoclet.taghandler namespace="Ojb"
0033: */
0034: public class OjbTagsHandler extends XDocletTagSupport {
0035: private static final String CONFIG_PARAM_CHECKS = "checks";
0036: private static final String CONFIG_PARAM_VERBOSE = "verbose";
0037: private static final String CONFIG_PARAM_DATABASENAME = "databaseName";
0038:
0039: private static final String ATTRIBUTE_CLASS = "class";
0040: private static final String ATTRIBUTE_CONSTANT = "constant";
0041: private static final String ATTRIBUTE_DEFAULT = "default";
0042: private static final String ATTRIBUTE_DEFAULT_RIGHT = "default-right";
0043: private static final String ATTRIBUTE_LEVEL = "level";
0044: private static final String ATTRIBUTE_NAME = "name";
0045: private static final String ATTRIBUTE_TYPE = "type";
0046: private static final String ATTRIBUTE_UNIQUE = "unique";
0047: private static final String ATTRIBUTE_VALUE = "value";
0048:
0049: private static final String LEVEL_CLASS = "class";
0050: private static final String LEVEL_COLLECTION = "collection";
0051: private static final String LEVEL_COLUMN = "column";
0052: private static final String LEVEL_FIELD = "field";
0053: private static final String LEVEL_FOREIGNKEY = "foreignkey";
0054: private static final String LEVEL_INDEX = "index";
0055: private static final String LEVEL_INDEX_DESC = "index-desc";
0056: private static final String LEVEL_OBJECT_CACHE = "object-cache";
0057: private static final String LEVEL_PROCEDURE = "procedure";
0058: private static final String LEVEL_PROCEDURE_ARGUMENT = "procedure-argument";
0059: private static final String LEVEL_REFERENCE = "reference";
0060: private static final String LEVEL_TABLE = "table";
0061:
0062: /** The ojb model */
0063: private ModelDef _model = new ModelDef();
0064: /** The torque model */
0065: private TorqueModelDef _torqueModel = null;
0066: /** The current class definition */
0067: private ClassDescriptorDef _curClassDef = null;
0068: /** The current field definition */
0069: private FieldDescriptorDef _curFieldDef = null;
0070: /** The current reference definition */
0071: private ReferenceDescriptorDef _curReferenceDef = null;
0072: /** The current collection definition */
0073: private CollectionDescriptorDef _curCollectionDef = null;
0074: /** The current extending class of the current extent */
0075: private ClassDescriptorDef _curExtent = null;
0076: /** The current obejct cache definition */
0077: private ObjectCacheDef _curObjectCacheDef = null;
0078: /** The current index descriptor definition */
0079: private IndexDescriptorDef _curIndexDescriptorDef = null;
0080: /** The current procedure definition */
0081: private ProcedureDef _curProcedureDef = null;
0082: /** The current procedure argument definition */
0083: private ProcedureArgumentDef _curProcedureArgumentDef = null;
0084: /** The name of the current index column */
0085: private String _curIndexColumn = null;
0086: /** The current table definition */
0087: private TableDef _curTableDef = null;
0088: /** The current column definition */
0089: private ColumnDef _curColumnDef = null;
0090: /** The current foreignkey definition */
0091: private ForeignkeyDef _curForeignkeyDef = null;
0092: /** The current index definition */
0093: private IndexDef _curIndexDef = null;
0094: /** The name of the current attribute */
0095: private String _curPairLeft = null;
0096: /** The value of the current attribute */
0097: private String _curPairRight = null;
0098:
0099: //
0100: // XDt methods
0101: //
0102:
0103: // Class-related
0104:
0105: /**
0106: * Sets the current class definition derived from the current class, and optionally some attributes.
0107: *
0108: * @param template The template
0109: * @param attributes The attributes of the tag
0110: * @exception XDocletException if an error occurs
0111: * @doc.tag type="block"
0112: * @doc.param name="accept-locks" optional="true" description="The accept locks setting" values="true,false"
0113: * @doc.param name="attributes" optional="true" description="Attributes of the class as name-value pairs 'name=value',
0114: * separated by commas"
0115: * @doc.param name="determine-extents" optional="true" description="Whether to determine
0116: * persistent direct sub types automatically" values="true,false"
0117: * @doc.param name="documentation" optional="true" description="Documentation on the class"
0118: * @doc.param name="factory-method" optional="true" description="Specifies a no-argument factory method that is
0119: * used to create instances (not yet implemented !)"
0120: * @doc.param name="factory-class" optional="true" description="Specifies a factory class to be used for creating
0121: * objects of this class"
0122: * @doc.param name="factory-method" optional="true" description="Specifies a static no-argument method in the factory class"
0123: * @doc.param name="generate-repository-info" optional="true" description="Whether repository data should be
0124: * generated for the class" values="true,false"
0125: * @doc.param name="generate-table-info" optional="true" description="Whether table data should be
0126: * generated for the class" values="true,false"
0127: * @doc.param name="include-inherited" optional="true" description="Whether to include
0128: * fields/references/collections of supertypes" values="true,false"
0129: * @doc.param name="initialization-method" optional="true" description="Specifies a no-argument instance method that is
0130: * called right after an instance has been read from the database"
0131: * @doc.param name="isolation-level" optional="true" description="The isolation level setting"
0132: * @doc.param name="proxy" optional="true" description="The proxy setting for this class"
0133: * @doc.param name="proxy-prefetching-limit" optional="true" description="Specifies the amount of objects of
0134: * objects of this class to prefetch in collections"
0135: * @doc.param name="refresh" optional="true" description="Can be set to force OJB to refresh instances when
0136: * loaded from the cache" values="true,false"
0137: * @doc.param name="row-reader" optional="true" description="The row reader for the class"
0138: * @doc.param name="schema" optional="true" description="The schema for the type"
0139: * @doc.param name="table" optional="true" description="The table for the class"
0140: * @doc.param name="table-documentation" optional="true" description="Documentation on the table"
0141: */
0142: public void processClass(String template, Properties attributes)
0143: throws XDocletException {
0144: if (!_model.hasClass(getCurrentClass().getQualifiedName())) {
0145: // we only want to output the log message once
0146: LogHelper.debug(true, OjbTagsHandler.class, "processClass",
0147: "Type " + getCurrentClass().getQualifiedName());
0148: }
0149:
0150: ClassDescriptorDef classDef = ensureClassDef(getCurrentClass());
0151: String attrName;
0152:
0153: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0154: .hasMoreElements();) {
0155: attrName = (String) attrNames.nextElement();
0156: classDef.setProperty(attrName, attributes
0157: .getProperty(attrName));
0158: }
0159: _curClassDef = classDef;
0160: generate(template);
0161: _curClassDef = null;
0162: }
0163:
0164: /**
0165: * Processes the template for all class definitions.
0166: *
0167: * @param template The template
0168: * @param attributes The attributes of the tag
0169: * @exception XDocletException if an error occurs
0170: * @doc.tag type="block"
0171: */
0172: public void forAllClassDefinitions(String template,
0173: Properties attributes) throws XDocletException {
0174: for (Iterator it = _model.getClasses(); it.hasNext();) {
0175: _curClassDef = (ClassDescriptorDef) it.next();
0176: generate(template);
0177: }
0178: _curClassDef = null;
0179:
0180: LogHelper.debug(true, OjbTagsHandler.class,
0181: "forAllClassDefinitions", "Processed "
0182: + _model.getNumClasses() + " types");
0183: }
0184:
0185: /**
0186: * Processes the original class rather than the current class definition.
0187: *
0188: * @param template The template
0189: * @param attributes The attributes of the tag
0190: * @exception XDocletException if an error occurs
0191: * @doc.tag type="block"
0192: */
0193: public void originalClass(String template, Properties attributes)
0194: throws XDocletException {
0195: pushCurrentClass(_curClassDef.getOriginalClass());
0196: generate(template);
0197: popCurrentClass();
0198: }
0199:
0200: /**
0201: * Processes all classes (flattens the hierarchy such that every class has declarations for all fields,
0202: * references,collections that it will have in the descriptor) and applies modifications (removes ignored
0203: * features, changes declarations).
0204: *
0205: * @return An empty string
0206: * @doc.tag type="content"
0207: */
0208: public String prepare() throws XDocletException {
0209: String checkLevel = (String) getDocletContext().getConfigParam(
0210: CONFIG_PARAM_CHECKS);
0211: ArrayList queue = new ArrayList();
0212: ClassDescriptorDef classDef, baseDef;
0213: XClass original;
0214: boolean isFinished;
0215:
0216: // determine inheritance relationships
0217: for (Iterator it = _model.getClasses(); it.hasNext();) {
0218: classDef = (ClassDescriptorDef) it.next();
0219: original = classDef.getOriginalClass();
0220: isFinished = false;
0221: queue.clear();
0222: while (!isFinished) {
0223: if (original == null) {
0224: isFinished = true;
0225: for (Iterator baseIt = queue.iterator(); baseIt
0226: .hasNext();) {
0227: original = (XClass) baseIt.next();
0228: baseDef = _model.getClass(original
0229: .getQualifiedName());
0230: baseIt.remove();
0231: if (baseDef != null) {
0232: classDef.addDirectBaseType(baseDef);
0233: } else {
0234: isFinished = false;
0235: break;
0236: }
0237: }
0238: }
0239: if (!isFinished) {
0240: if (original.getInterfaces() != null) {
0241: for (Iterator baseIt = original.getInterfaces()
0242: .iterator(); baseIt.hasNext();) {
0243: queue.add(baseIt.next());
0244: }
0245: }
0246: if (original.getSuperclass() != null) {
0247: queue.add(original.getSuperclass());
0248: }
0249: original = null;
0250: }
0251: }
0252: }
0253: try {
0254: _model.process();
0255: _model.checkConstraints(checkLevel);
0256: } catch (ConstraintException ex) {
0257: throw new XDocletException(ex.getMessage());
0258: }
0259: return "";
0260: }
0261:
0262: // Extent-related
0263:
0264: /**
0265: * The <code>forAllSubClasses</code> method iterates through all sub types of the current type (classes if it is a
0266: * class or classes and interfaces for an interface).
0267: *
0268: * @param template The template
0269: * @param attributes The attributes of the tag
0270: * @exception XDocletException if an error occurs
0271: * @doc.tag type="block"
0272: */
0273: public void forAllSubClasses(String template, Properties attributes)
0274: throws XDocletException {
0275: ArrayList subTypes = new ArrayList();
0276: XClass type = getCurrentClass();
0277:
0278: addDirectSubTypes(type, subTypes);
0279:
0280: int pos = 0;
0281: ClassDescriptorDef classDef;
0282:
0283: while (pos < subTypes.size()) {
0284: type = (XClass) subTypes.get(pos);
0285: classDef = _model.getClass(type.getQualifiedName());
0286: if ((classDef != null)
0287: && classDef
0288: .hasProperty(PropertyHelper.OJB_PROPERTY_OJB_PERSISTENT)) {
0289: pos++;
0290: } else {
0291: subTypes.remove(pos);
0292: addDirectSubTypes(type, subTypes);
0293: }
0294: }
0295: for (Iterator it = subTypes.iterator(); it.hasNext();) {
0296: pushCurrentClass((XClass) it.next());
0297: generate(template);
0298: popCurrentClass();
0299: }
0300: }
0301:
0302: /**
0303: * Adds an extent relation to the current class definition.
0304: *
0305: * @param attributes The attributes of the tag
0306: * @return An empty string
0307: * @exception XDocletException If an error occurs
0308: * @doc.tag type="content"
0309: * @doc.param name="name" optional="false" description="The fully qualified name of the extending
0310: * class"
0311: */
0312: public String addExtent(Properties attributes)
0313: throws XDocletException {
0314: String name = attributes.getProperty(ATTRIBUTE_NAME);
0315:
0316: if (!_model.hasClass(name)) {
0317: throw new XDocletException(Translator.getString(
0318: XDocletModulesOjbMessages.class,
0319: XDocletModulesOjbMessages.COULD_NOT_FIND_TYPE,
0320: new String[] { name }));
0321: }
0322: _curClassDef.addExtentClass(_model.getClass(name));
0323: return "";
0324: }
0325:
0326: /**
0327: * Processes the template for all extents of the current class.
0328: *
0329: * @param template The template
0330: * @param attributes The attributes of the tag
0331: * @exception XDocletException if an error occurs
0332: * @doc.tag type="block"
0333: */
0334: public void forAllExtents(String template, Properties attributes)
0335: throws XDocletException {
0336: for (Iterator it = _curClassDef.getExtentClasses(); it
0337: .hasNext();) {
0338: _curExtent = (ClassDescriptorDef) it.next();
0339: generate(template);
0340: }
0341: _curExtent = null;
0342: }
0343:
0344: /**
0345: * Returns the qualified name of the current extent.
0346: *
0347: * @param attributes The attributes of the tag
0348: * @return The qualified name of the extent class
0349: * @exception XDocletException If an error occurs
0350: * @doc.tag type="content"
0351: */
0352: public String extent(Properties attributes) throws XDocletException {
0353: return _curExtent.getName();
0354: }
0355:
0356: // Index-related
0357:
0358: /**
0359: * Processes an index descriptor tag.
0360: *
0361: * @param template The template
0362: * @param attributes The attributes of the tag
0363: * @exception XDocletException If an error occurs
0364: * @doc.tag type="content"
0365: * @doc.param name="documentation" optional="true" description="Documentation on the index"
0366: * @doc.param name="fields" optional="false" description="The fields making up the index separated by commas"
0367: * @doc.param name="name" optional="false" description="The name of the index descriptor"
0368: * @doc.param name="unique" optional="true" description="Whether the index descriptor is unique" values="true,false"
0369: */
0370: public String processIndexDescriptor(Properties attributes)
0371: throws XDocletException {
0372: String name = attributes.getProperty(ATTRIBUTE_NAME);
0373: IndexDescriptorDef indexDef = _curClassDef
0374: .getIndexDescriptor(name);
0375: String attrName;
0376:
0377: if (indexDef == null) {
0378: indexDef = new IndexDescriptorDef(name);
0379: _curClassDef.addIndexDescriptor(indexDef);
0380: }
0381:
0382: if ((indexDef.getName() == null)
0383: || (indexDef.getName().length() == 0)) {
0384: throw new XDocletException(Translator.getString(
0385: XDocletModulesOjbMessages.class,
0386: XDocletModulesOjbMessages.INDEX_NAME_MISSING,
0387: new String[] { _curClassDef.getName() }));
0388: }
0389: attributes.remove(ATTRIBUTE_NAME);
0390: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0391: .hasMoreElements();) {
0392: attrName = (String) attrNames.nextElement();
0393: indexDef.setProperty(attrName, attributes
0394: .getProperty(attrName));
0395: }
0396: return "";
0397: }
0398:
0399: /**
0400: * Processes the template for all index descriptors of the current class definition.
0401: *
0402: * @param template The template
0403: * @param attributes The attributes of the tag
0404: * @exception XDocletException if an error occurs
0405: * @doc.tag type="block"
0406: */
0407: public void forAllIndexDescriptorDefinitions(String template,
0408: Properties attributes) throws XDocletException {
0409: for (Iterator it = _curClassDef.getIndexDescriptors(); it
0410: .hasNext();) {
0411: _curIndexDescriptorDef = (IndexDescriptorDef) it.next();
0412: generate(template);
0413: }
0414: _curIndexDescriptorDef = null;
0415: }
0416:
0417: /**
0418: * Processes the template for all index columns for the current index descriptor.
0419: *
0420: * @param template The template
0421: * @param attributes The attributes of the tag
0422: * @exception XDocletException if an error occurs
0423: * @doc.tag type="block"
0424: */
0425: public void forAllIndexDescriptorColumns(String template,
0426: Properties attributes) throws XDocletException {
0427: String fields = _curIndexDescriptorDef
0428: .getProperty(PropertyHelper.OJB_PROPERTY_FIELDS);
0429: FieldDescriptorDef fieldDef;
0430: String name;
0431:
0432: for (CommaListIterator it = new CommaListIterator(fields); it
0433: .hasNext();) {
0434: name = it.getNext();
0435: fieldDef = _curClassDef.getField(name);
0436: if (fieldDef == null) {
0437: throw new XDocletException(Translator.getString(
0438: XDocletModulesOjbMessages.class,
0439: XDocletModulesOjbMessages.INDEX_FIELD_MISSING,
0440: new String[] { name,
0441: _curIndexDescriptorDef.getName(),
0442: _curClassDef.getName() }));
0443: }
0444: _curIndexColumn = fieldDef
0445: .getProperty(PropertyHelper.OJB_PROPERTY_COLUMN);
0446: generate(template);
0447: }
0448: _curIndexColumn = null;
0449: }
0450:
0451: /**
0452: * Returns the current index column.
0453: *
0454: * @param attributes The attributes of the tag
0455: * @return The index column
0456: * @exception XDocletException If an error occurs
0457: * @doc.tag type="content"
0458: */
0459: public String indexColumn(Properties attributes)
0460: throws XDocletException {
0461: return _curIndexColumn;
0462: }
0463:
0464: // Object-cache related
0465:
0466: /**
0467: * Processes an object cache tag.
0468: *
0469: * @param template The template
0470: * @param attributes The attributes of the tag
0471: * @exception XDocletException If an error occurs
0472: * @doc.tag type="content"
0473: * @doc.param name="attributes" optional="true" description="Attributes of the object-cache as name-value pairs 'name=value',
0474: * @doc.param name="class" optional="false" description="The object cache implementation"
0475: * @doc.param name="documentation" optional="true" description="Documentation on the object cache"
0476: */
0477: public String processObjectCache(Properties attributes)
0478: throws XDocletException {
0479: ObjectCacheDef objCacheDef = _curClassDef
0480: .setObjectCache(attributes.getProperty(ATTRIBUTE_CLASS));
0481: String attrName;
0482:
0483: attributes.remove(ATTRIBUTE_CLASS);
0484: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0485: .hasMoreElements();) {
0486: attrName = (String) attrNames.nextElement();
0487: objCacheDef.setProperty(attrName, attributes
0488: .getProperty(attrName));
0489: }
0490: return "";
0491: }
0492:
0493: /**
0494: * Processes the template for the object cache of the current class definition.
0495: *
0496: * @param template The template
0497: * @param attributes The attributes of the tag
0498: * @exception XDocletException if an error occurs
0499: * @doc.tag type="block"
0500: */
0501: public void forObjectCache(String template, Properties attributes)
0502: throws XDocletException {
0503: _curObjectCacheDef = _curClassDef.getObjectCache();
0504: if (_curObjectCacheDef != null) {
0505: generate(template);
0506: _curObjectCacheDef = null;
0507: }
0508: }
0509:
0510: // Procedure-related
0511:
0512: /**
0513: * Processes a procedure tag.
0514: *
0515: * @param template The template
0516: * @param attributes The attributes of the tag
0517: * @exception XDocletException If an error occurs
0518: * @doc.tag type="content"
0519: * @doc.param name="arguments" optional="true" description="The arguments of the procedure as a comma-separated
0520: * list of names of procedure attribute tags"
0521: * @doc.param name="attributes" optional="true" description="Attributes of the procedure as name-value pairs 'name=value',
0522: * separated by commas"
0523: * @doc.param name="documentation" optional="true" description="Documentation on the procedure"
0524: * @doc.param name="include-all-fields" optional="true" description="For insert/update: whether all fields of the current
0525: * class shall be included (arguments is ignored then)" values="true,false"
0526: * @doc.param name="include-pk-only" optional="true" description="For delete: whether all primary key fields
0527: * shall be included (arguments is ignored then)" values="true,false"
0528: * @doc.param name="name" optional="false" description="The name of the procedure"
0529: * @doc.param name="return-field-ref" optional="true" description="Identifies the field that receives the return value"
0530: * @doc.param name="type" optional="false" description="The type of the procedure" values="delete,insert,update"
0531: */
0532: public String processProcedure(Properties attributes)
0533: throws XDocletException {
0534: String type = attributes.getProperty(ATTRIBUTE_TYPE);
0535: ProcedureDef procDef = _curClassDef.getProcedure(type);
0536: String attrName;
0537:
0538: if (procDef == null) {
0539: procDef = new ProcedureDef(type);
0540: _curClassDef.addProcedure(procDef);
0541: }
0542:
0543: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0544: .hasMoreElements();) {
0545: attrName = (String) attrNames.nextElement();
0546: procDef.setProperty(attrName, attributes
0547: .getProperty(attrName));
0548: }
0549: return "";
0550: }
0551:
0552: /**
0553: * Processes the template for all procedures of the current class definition.
0554: *
0555: * @param template The template
0556: * @param attributes The attributes of the tag
0557: * @exception XDocletException if an error occurs
0558: * @doc.tag type="block"
0559: */
0560: public void forAllProcedures(String template, Properties attributes)
0561: throws XDocletException {
0562: for (Iterator it = _curClassDef.getProcedures(); it.hasNext();) {
0563: _curProcedureDef = (ProcedureDef) it.next();
0564: generate(template);
0565: }
0566: _curProcedureDef = null;
0567: }
0568:
0569: /**
0570: * Processes a runtime procedure argument tag.
0571: *
0572: * @param template The template
0573: * @param attributes The attributes of the tag
0574: * @exception XDocletException If an error occurs
0575: * @doc.tag type="content"
0576: * @doc.param name="attributes" optional="true" description="Attributes of the procedure as name-value pairs 'name=value',
0577: * separated by commas"
0578: * @doc.param name="documentation" optional="true" description="Documentation on the procedure"
0579: * @doc.param name="field-ref" optional="true" description="Identifies the field that provides the value
0580: * if a runtime argument; if not set, then null is used"
0581: * @doc.param name="name" optional="false" description="The identifier of the argument tag"
0582: * @doc.param name="return" optional="true" description="Whether this is a return value (if a runtime argument)"
0583: * values="true,false"
0584: * @doc.param name="value" optional="false" description="The value if a constant argument"
0585: */
0586: public String processProcedureArgument(Properties attributes)
0587: throws XDocletException {
0588: String id = attributes.getProperty(ATTRIBUTE_NAME);
0589: ProcedureArgumentDef argDef = _curClassDef
0590: .getProcedureArgument(id);
0591: String attrName;
0592:
0593: if (argDef == null) {
0594: argDef = new ProcedureArgumentDef(id);
0595: _curClassDef.addProcedureArgument(argDef);
0596: }
0597:
0598: attributes.remove(ATTRIBUTE_NAME);
0599: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0600: .hasMoreElements();) {
0601: attrName = (String) attrNames.nextElement();
0602: argDef.setProperty(attrName, attributes
0603: .getProperty(attrName));
0604: }
0605: return "";
0606: }
0607:
0608: /**
0609: * Processes the template for all procedure arguments of the current procedure.
0610: *
0611: * @param template The template
0612: * @param attributes The attributes of the tag
0613: * @exception XDocletException if an error occurs
0614: * @doc.tag type="block"
0615: */
0616: public void forAllProcedureArguments(String template,
0617: Properties attributes) throws XDocletException {
0618: String argNameList = _curProcedureDef
0619: .getProperty(PropertyHelper.OJB_PROPERTY_ARGUMENTS);
0620:
0621: for (CommaListIterator it = new CommaListIterator(argNameList); it
0622: .hasNext();) {
0623: _curProcedureArgumentDef = _curClassDef
0624: .getProcedureArgument(it.getNext());
0625: generate(template);
0626: }
0627: _curProcedureArgumentDef = null;
0628: }
0629:
0630: // Field-related
0631:
0632: /**
0633: * Processes an anonymous field definition specified at the class level.
0634: *
0635: * @param attributes The attributes of the tag
0636: * @exception XDocletException if an error occurs
0637: * @doc.tag type="content"
0638: * @doc.param name="attributes" optional="true" description="Attributes of the field as name-value pairs 'name=value',
0639: * separated by commas"
0640: * @doc.param name="autoincrement" optional="true" description="Whether the field is
0641: * auto-incremented" values="true,false"
0642: * @doc.param name="column" optional="true" description="The column for the field"
0643: * @doc.param name="conversion" optional="true" description="The fully qualified name of the
0644: * conversion for the field"
0645: * @doc.param name="default-fetch" optional="true" description="The default-fetch setting"
0646: * values="true,false"
0647: * @doc.param name="documentation" optional="true" description="Documentation on the field"
0648: * @doc.param name="id" optional="true" description="The position of the field in the class
0649: * descriptor"
0650: * @doc.param name="indexed" optional="true" description="Whether the field is indexed"
0651: * values="true,false"
0652: * @doc.param name="jdbc-type" optional="true" description="The jdbc type of the column"
0653: * @doc.param name="length" optional="true" description="The length of the column"
0654: * @doc.param name="locking" optional="true" description="Whether the field supports locking"
0655: * values="true,false"
0656: * @doc.param name="name" optional="false" description="The name of the field"
0657: * @doc.param name="nullable" optional="true" description="Whether the field is nullable"
0658: * values="true,false"
0659: * @doc.param name="precision" optional="true" description="The precision of the column"
0660: * @doc.param name="primarykey" optional="true" description="Whether the field is a primarykey"
0661: * values="true,false"
0662: * @doc.param name="scale" optional="true" description="The scale of the column"
0663: * @doc.param name="sequence-name" optional="true" description="The name of the sequence for
0664: * incrementing the field"
0665: * @doc.param name="table" optional="true" description="The table of the field (not implemented
0666: * yet)"
0667: * @doc.param name="update-lock" optional="true" description="Can be set to false if the persistent attribute is
0668: * used for optimistic locking AND the dbms should update the lock column itself (default is true). Can only be set for
0669: * TIMESTAMP and INTEGER columns" values="true,false"
0670: */
0671: public void processAnonymousField(Properties attributes)
0672: throws XDocletException {
0673: if (!attributes.containsKey(ATTRIBUTE_NAME)) {
0674: throw new XDocletException(Translator.getString(
0675: XDocletModulesOjbMessages.class,
0676: XDocletModulesOjbMessages.PARAMETER_IS_REQUIRED,
0677: new String[] { ATTRIBUTE_NAME }));
0678: }
0679:
0680: String name = attributes.getProperty(ATTRIBUTE_NAME);
0681: FieldDescriptorDef fieldDef = _curClassDef.getField(name);
0682: String attrName;
0683:
0684: if (fieldDef == null) {
0685: fieldDef = new FieldDescriptorDef(name);
0686: _curClassDef.addField(fieldDef);
0687: }
0688: fieldDef.setAnonymous();
0689: LogHelper.debug(false, OjbTagsHandler.class,
0690: "processAnonymousField",
0691: " Processing anonymous field " + fieldDef.getName());
0692:
0693: attributes.remove(ATTRIBUTE_NAME);
0694: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0695: .hasMoreElements();) {
0696: attrName = (String) attrNames.nextElement();
0697: fieldDef.setProperty(attrName, attributes
0698: .getProperty(attrName));
0699: }
0700: fieldDef.setProperty(PropertyHelper.OJB_PROPERTY_ACCESS,
0701: "anonymous");
0702: }
0703:
0704: /**
0705: * Sets the current field definition derived from the current member, and optionally some attributes.
0706: *
0707: * @param template The template
0708: * @param attributes The attributes of the tag
0709: * @exception XDocletException if an error occurs
0710: * @doc.tag type="block"
0711: * @doc.param name="access" optional="true" description="The accessibility of the column" values="readonly,readwrite"
0712: * @doc.param name="attributes" optional="true" description="Attributes of the field as name-value pairs 'name=value',
0713: * separated by commas"
0714: * @doc.param name="autoincrement" optional="true" description="Whether the field is
0715: * auto-incremented" values="none,ojb,database"
0716: * @doc.param name="column" optional="true" description="The column for the field"
0717: * @doc.param name="column-documentation" optional="true" description="Documentation on the column"
0718: * @doc.param name="conversion" optional="true" description="The fully qualified name of the
0719: * conversion for the field"
0720: * @doc.param name="default-fetch" optional="true" description="The default-fetch setting"
0721: * values="true,false"
0722: * @doc.param name="documentation" optional="true" description="Documentation on the field"
0723: * @doc.param name="id" optional="true" description="The position of the field in the class
0724: * descriptor"
0725: * @doc.param name="indexed" optional="true" description="Whether the field is indexed"
0726: * values="true,false"
0727: * @doc.param name="jdbc-type" optional="true" description="The jdbc type of the column"
0728: * @doc.param name="length" optional="true" description="The length of the column"
0729: * @doc.param name="locking" optional="true" description="Whether the field supports locking"
0730: * values="true,false"
0731: * @doc.param name="nullable" optional="true" description="Whether the field is nullable"
0732: * values="true,false"
0733: * @doc.param name="precision" optional="true" description="The precision of the column"
0734: * @doc.param name="primarykey" optional="true" description="Whether the field is a primarykey"
0735: * values="true,false"
0736: * @doc.param name="scale" optional="true" description="The scale of the column"
0737: * @doc.param name="sequence-name" optional="true" description="The name of the sequence for
0738: * incrementing the field"
0739: * @doc.param name="table" optional="true" description="The table of the field (not implemented
0740: * yet)"
0741: * @doc.param name="update-lock" optional="true" description="Can be set to false if the persistent attribute is
0742: * used for optimistic locking AND the dbms should update the lock column itself (default is true). Can only be set for
0743: * TIMESTAMP and INTEGER columns" values="true,false"
0744: */
0745: public void processField(String template, Properties attributes)
0746: throws XDocletException {
0747: String name = OjbMemberTagsHandler.getMemberName();
0748: String defaultType = getDefaultJdbcTypeForCurrentMember();
0749: String defaultConversion = getDefaultJdbcConversionForCurrentMember();
0750: FieldDescriptorDef fieldDef = _curClassDef.getField(name);
0751: String attrName;
0752:
0753: if (fieldDef == null) {
0754: fieldDef = new FieldDescriptorDef(name);
0755: _curClassDef.addField(fieldDef);
0756: }
0757: LogHelper.debug(false, OjbTagsHandler.class, "processField",
0758: " Processing field " + fieldDef.getName());
0759:
0760: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0761: .hasMoreElements();) {
0762: attrName = (String) attrNames.nextElement();
0763: fieldDef.setProperty(attrName, attributes
0764: .getProperty(attrName));
0765: }
0766: // storing additional info for later use
0767: fieldDef
0768: .setProperty(PropertyHelper.OJB_PROPERTY_JAVA_TYPE,
0769: OjbMemberTagsHandler.getMemberType()
0770: .getQualifiedName());
0771: fieldDef.setProperty(
0772: PropertyHelper.OJB_PROPERTY_DEFAULT_JDBC_TYPE,
0773: defaultType);
0774: if (defaultConversion != null) {
0775: fieldDef.setProperty(
0776: PropertyHelper.OJB_PROPERTY_DEFAULT_CONVERSION,
0777: defaultConversion);
0778: }
0779:
0780: _curFieldDef = fieldDef;
0781: generate(template);
0782: _curFieldDef = null;
0783: }
0784:
0785: /**
0786: * Processes the template for all field definitions of the current class definition (including inherited ones if
0787: * required)
0788: *
0789: * @param template The template
0790: * @param attributes The attributes of the tag
0791: * @exception XDocletException if an error occurs
0792: * @doc.tag type="block"
0793: */
0794: public void forAllFieldDefinitions(String template,
0795: Properties attributes) throws XDocletException {
0796: for (Iterator it = _curClassDef.getFields(); it.hasNext();) {
0797: _curFieldDef = (FieldDescriptorDef) it.next();
0798: if (!isFeatureIgnored(LEVEL_FIELD)
0799: && !_curFieldDef.getBooleanProperty(
0800: PropertyHelper.OJB_PROPERTY_IGNORE, false)) {
0801: generate(template);
0802: }
0803: }
0804: _curFieldDef = null;
0805: }
0806:
0807: /**
0808: * Returns the constraint (length or precision+scale) for the jdbc type of the current field.
0809: *
0810: * @param attributes The attributes of the tag
0811: * @return The constraint of the field
0812: * @exception XDocletException If an error occurs
0813: * @doc.tag type="content"
0814: */
0815: public String fieldConstraint(Properties attributes)
0816: throws XDocletException {
0817: return _curFieldDef.getSizeConstraint();
0818: }
0819:
0820: // Reference-related
0821:
0822: /**
0823: * Processes an anonymous reference definition.
0824: *
0825: * @param attributes The attributes of the tag
0826: * @exception XDocletException If an error occurs
0827: * @doc.tag type="content"
0828: * @doc.param name="attributes" optional="true" description="Attributes of the reference as name-value pairs 'name=value',
0829: * separated by commas"
0830: * @doc.param name="auto-delete" optional="true" description="Whether to automatically delete the
0831: * referenced object on object deletion"
0832: * @doc.param name="auto-retrieve" optional="true" description="Whether to automatically retrieve
0833: * the referenced object"
0834: * @doc.param name="auto-update" optional="true" description="Whether to automatically update the
0835: * referenced object"
0836: * @doc.param name="class-ref" optional="false" description="The fully qualified name of the class
0837: * owning the referenced field"
0838: * @doc.param name="documentation" optional="true" description="Documentation on the reference"
0839: * @doc.param name="foreignkey" optional="true" description="The fields in the current type used for
0840: * implementing the reference"
0841: * @doc.param name="otm-dependent" optional="true" description="Whether the reference is dependent on otm"
0842: * @doc.param name="proxy" optional="true" description="Whether to use a proxy for the reference"
0843: * @doc.param name="proxy-prefetching-limit" optional="true" description="Specifies the amount of objects to prefetch"
0844: * @doc.param name="refresh" optional="true" description="Whether to automatically refresh the
0845: * reference"
0846: * @doc.param name="remote-foreignkey" optional="true" description="The fields in the referenced type
0847: * corresponding to the local fields (is only used for the table definition)"
0848: */
0849: public void processAnonymousReference(Properties attributes)
0850: throws XDocletException {
0851: ReferenceDescriptorDef refDef = _curClassDef
0852: .getReference("super");
0853: String attrName;
0854:
0855: if (refDef == null) {
0856: refDef = new ReferenceDescriptorDef("super");
0857: _curClassDef.addReference(refDef);
0858: }
0859: refDef.setAnonymous();
0860: LogHelper.debug(false, OjbTagsHandler.class,
0861: "processAnonymousReference",
0862: " Processing anonymous reference");
0863:
0864: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0865: .hasMoreElements();) {
0866: attrName = (String) attrNames.nextElement();
0867: refDef.setProperty(attrName, attributes
0868: .getProperty(attrName));
0869: }
0870: }
0871:
0872: /**
0873: * Sets the current reference definition derived from the current member, and optionally some attributes.
0874: *
0875: * @param template The template
0876: * @param attributes The attributes of the tag
0877: * @exception XDocletException If an error occurs
0878: * @doc.tag type="block"
0879: * @doc.param name="attributes" optional="true" description="Attributes of the reference as name-value pairs 'name=value',
0880: * separated by commas"
0881: * @doc.param name="auto-delete" optional="true" description="Whether to automatically delete the
0882: * referenced object on object deletion"
0883: * @doc.param name="auto-retrieve" optional="true" description="Whether to automatically retrieve
0884: * the referenced object"
0885: * @doc.param name="auto-update" optional="true" description="Whether to automatically update the
0886: * referenced object"
0887: * @doc.param name="class-ref" optional="true" description="The fully qualified name of the class
0888: * owning the referenced field"
0889: * @doc.param name="database-foreignkey" optional="true" description="Whether a database foreignkey shall be created"
0890: * values="true,false"
0891: * @doc.param name="documentation" optional="true" description="Documentation on the reference"
0892: * @doc.param name="foreignkey" optional="true" description="The fields in the current type used for
0893: * implementing the reference"
0894: * @doc.param name="otm-dependent" optional="true" description="Whether the reference is dependent on otm"
0895: * @doc.param name="proxy" optional="true" description="Whether to use a proxy for the reference"
0896: * @doc.param name="proxy-prefetching-limit" optional="true" description="Specifies the amount of objects to prefetch"
0897: * @doc.param name="refresh" optional="true" description="Whether to automatically refresh the
0898: * reference"
0899: * @doc.param name="remote-foreignkey" optional="true" description="The fields in the referenced type
0900: * corresponding to the local fields (is only used for the table definition)"
0901: */
0902: public void processReference(String template, Properties attributes)
0903: throws XDocletException {
0904: String name = OjbMemberTagsHandler.getMemberName();
0905: XClass type = OjbMemberTagsHandler.getMemberType();
0906: int dim = OjbMemberTagsHandler.getMemberDimension();
0907: ReferenceDescriptorDef refDef = _curClassDef.getReference(name);
0908: String attrName;
0909:
0910: if (refDef == null) {
0911: refDef = new ReferenceDescriptorDef(name);
0912: _curClassDef.addReference(refDef);
0913: }
0914: LogHelper.debug(false, OjbTagsHandler.class,
0915: "processReference", " Processing reference "
0916: + refDef.getName());
0917:
0918: for (Enumeration attrNames = attributes.propertyNames(); attrNames
0919: .hasMoreElements();) {
0920: attrName = (String) attrNames.nextElement();
0921: refDef.setProperty(attrName, attributes
0922: .getProperty(attrName));
0923: }
0924: // storing default info for later use
0925: if (type == null) {
0926: throw new XDocletException(
0927: Translator
0928: .getString(
0929: XDocletModulesOjbMessages.class,
0930: XDocletModulesOjbMessages.COULD_NOT_DETERMINE_TYPE_OF_MEMBER,
0931: new String[] { name }));
0932: }
0933: if (dim > 0) {
0934: throw new XDocletException(
0935: Translator
0936: .getString(
0937: XDocletModulesOjbMessages.class,
0938: XDocletModulesOjbMessages.MEMBER_CANNOT_BE_A_REFERENCE,
0939: new String[] { name,
0940: _curClassDef.getName() }));
0941: }
0942:
0943: refDef.setProperty(PropertyHelper.OJB_PROPERTY_VARIABLE_TYPE,
0944: type.getQualifiedName());
0945:
0946: // searching for default type
0947: String typeName = searchForPersistentSubType(type);
0948:
0949: if (typeName != null) {
0950: refDef.setProperty(
0951: PropertyHelper.OJB_PROPERTY_DEFAULT_CLASS_REF,
0952: typeName);
0953: }
0954:
0955: _curReferenceDef = refDef;
0956: generate(template);
0957: _curReferenceDef = null;
0958: }
0959:
0960: /**
0961: * Processes the template for all reference definitions of the current class definition.
0962: *
0963: * @param template The template
0964: * @param attributes The attributes of the tag
0965: * @exception XDocletException if an error occurs
0966: * @doc.tag type="block"
0967: */
0968: public void forAllReferenceDefinitions(String template,
0969: Properties attributes) throws XDocletException {
0970: for (Iterator it = _curClassDef.getReferences(); it.hasNext();) {
0971: _curReferenceDef = (ReferenceDescriptorDef) it.next();
0972: // first we check whether it is an inherited anonymous reference
0973: if (_curReferenceDef.isAnonymous()
0974: && (_curReferenceDef.getOwner() != _curClassDef)) {
0975: continue;
0976: }
0977: if (!isFeatureIgnored(LEVEL_REFERENCE)
0978: && !_curReferenceDef.getBooleanProperty(
0979: PropertyHelper.OJB_PROPERTY_IGNORE, false)) {
0980: generate(template);
0981: }
0982: }
0983: _curReferenceDef = null;
0984: }
0985:
0986: // Collection-related
0987:
0988: /**
0989: * Sets the current collection definition derived from the current member, and optionally some attributes.
0990: *
0991: * @param template The template
0992: * @param attributes The attributes of the tag
0993: * @exception XDocletException If an error occurs
0994: * @doc.tag type="block"
0995: * @doc.param name="attributes" optional="true" description="Attributes of the collection as name-value pairs 'name=value',
0996: * separated by commas"
0997: * @doc.param name="auto-delete" optional="true" description="Whether to automatically delete the
0998: * collection on object deletion"
0999: * @doc.param name="auto-retrieve" optional="true" description="Whether to automatically retrieve
1000: * the collection"
1001: * @doc.param name="auto-update" optional="true" description="Whether to automatically update the
1002: * collection"
1003: * @doc.param name="collection-class" optional="true" description="The type of the collection if not a
1004: * java.util type or an array"
1005: * @doc.param name="database-foreignkey" optional="true" description="Whether a database foreignkey shall be created"
1006: * values="true,false"
1007: * @doc.param name="documentation" optional="true" description="Documentation on the collection"
1008: * @doc.param name="element-class-ref" optional="true" description="The fully qualified name of
1009: * the element type"
1010: * @doc.param name="foreignkey" optional="true" description="The name of the
1011: * foreign keys (columns when an indirection table is given)"
1012: * @doc.param name="foreignkey-documentation" optional="true" description="Documentation
1013: * on the foreign keys as a comma-separated list if using an indirection table"
1014: * @doc.param name="indirection-table" optional="true" description="The name of the indirection
1015: * table for m:n associations"
1016: * @doc.param name="indirection-table-documentation" optional="true" description="Documentation
1017: * on the indirection table"
1018: * @doc.param name="indirection-table-primarykeys" optional="true" description="Whether the
1019: * fields referencing the collection and element classes, should also be primarykeys"
1020: * @doc.param name="otm-dependent" optional="true" description="Whether the collection is dependent on otm"
1021: * @doc.param name="proxy" optional="true" description="Whether to use a proxy for the collection"
1022: * @doc.param name="proxy-prefetching-limit" optional="true" description="Specifies the amount of objects to prefetch"
1023: * @doc.param name="query-customizer" optional="true" description="The query customizer for this collection"
1024: * @doc.param name="query-customizer-attributes" optional="true" description="Attributes for the query customizer"
1025: * @doc.param name="refresh" optional="true" description="Whether to automatically refresh the
1026: * collection"
1027: * @doc.param name="remote-foreignkey" optional="true" description="The name of the
1028: * foreign key columns pointing to the elements if using an indirection table"
1029: * @doc.param name="remote-foreignkey-documentation" optional="true" description="Documentation
1030: * on the remote foreign keys as a comma-separated list if using an indirection table"
1031: */
1032: public void processCollection(String template, Properties attributes)
1033: throws XDocletException {
1034: String name = OjbMemberTagsHandler.getMemberName();
1035: CollectionDescriptorDef collDef = _curClassDef
1036: .getCollection(name);
1037: String attrName;
1038:
1039: if (collDef == null) {
1040: collDef = new CollectionDescriptorDef(name);
1041: _curClassDef.addCollection(collDef);
1042: }
1043: LogHelper.debug(false, OjbTagsHandler.class,
1044: "processCollection", " Processing collection "
1045: + collDef.getName());
1046:
1047: for (Enumeration attrNames = attributes.propertyNames(); attrNames
1048: .hasMoreElements();) {
1049: attrName = (String) attrNames.nextElement();
1050: collDef.setProperty(attrName, attributes
1051: .getProperty(attrName));
1052: }
1053: if (OjbMemberTagsHandler.getMemberDimension() > 0) {
1054: // we store the array-element type for later use
1055: collDef
1056: .setProperty(
1057: PropertyHelper.OJB_PROPERTY_ARRAY_ELEMENT_CLASS_REF,
1058: OjbMemberTagsHandler.getMemberType()
1059: .getQualifiedName());
1060: } else {
1061: collDef.setProperty(
1062: PropertyHelper.OJB_PROPERTY_VARIABLE_TYPE,
1063: OjbMemberTagsHandler.getMemberType()
1064: .getQualifiedName());
1065: }
1066:
1067: _curCollectionDef = collDef;
1068: generate(template);
1069: _curCollectionDef = null;
1070: }
1071:
1072: /**
1073: * Processes the template for all collection definitions of the current class definition.
1074: *
1075: * @param template The template
1076: * @param attributes The attributes of the tag
1077: * @exception XDocletException if an error occurs
1078: * @doc.tag type="block"
1079: */
1080: public void forAllCollectionDefinitions(String template,
1081: Properties attributes) throws XDocletException {
1082: for (Iterator it = _curClassDef.getCollections(); it.hasNext();) {
1083: _curCollectionDef = (CollectionDescriptorDef) it.next();
1084: if (!isFeatureIgnored(LEVEL_COLLECTION)
1085: && !_curCollectionDef.getBooleanProperty(
1086: PropertyHelper.OJB_PROPERTY_IGNORE, false)) {
1087: generate(template);
1088: }
1089: }
1090: _curCollectionDef = null;
1091: }
1092:
1093: /**
1094: * Addes the current member as a nested object.
1095: *
1096: * @param template The template
1097: * @param attributes The attributes of the tag
1098: * @exception XDocletException If an error occurs
1099: * @doc.tag type="content"
1100: */
1101: public String processNested(Properties attributes)
1102: throws XDocletException {
1103: String name = OjbMemberTagsHandler.getMemberName();
1104: XClass type = OjbMemberTagsHandler.getMemberType();
1105: int dim = OjbMemberTagsHandler.getMemberDimension();
1106: NestedDef nestedDef = _curClassDef.getNested(name);
1107:
1108: if (type == null) {
1109: throw new XDocletException(
1110: Translator
1111: .getString(
1112: XDocletModulesOjbMessages.class,
1113: XDocletModulesOjbMessages.COULD_NOT_DETERMINE_TYPE_OF_MEMBER,
1114: new String[] { name }));
1115: }
1116: if (dim > 0) {
1117: throw new XDocletException(Translator.getString(
1118: XDocletModulesOjbMessages.class,
1119: XDocletModulesOjbMessages.MEMBER_CANNOT_BE_NESTED,
1120: new String[] { name, _curClassDef.getName() }));
1121: }
1122:
1123: ClassDescriptorDef nestedTypeDef = _model.getClass(type
1124: .getQualifiedName());
1125:
1126: if (nestedTypeDef == null) {
1127: throw new XDocletException(
1128: Translator
1129: .getString(
1130: XDocletModulesOjbMessages.class,
1131: XDocletModulesOjbMessages.COULD_NOT_DETERMINE_TYPE_OF_MEMBER,
1132: new String[] { name }));
1133: }
1134: if (nestedDef == null) {
1135: nestedDef = new NestedDef(name, nestedTypeDef);
1136: _curClassDef.addNested(nestedDef);
1137: }
1138: LogHelper.debug(false, OjbTagsHandler.class, "processNested",
1139: " Processing nested object " + nestedDef.getName()
1140: + " of type " + nestedTypeDef.getName());
1141:
1142: String attrName;
1143:
1144: for (Enumeration attrNames = attributes.propertyNames(); attrNames
1145: .hasMoreElements();) {
1146: attrName = (String) attrNames.nextElement();
1147: nestedDef.setProperty(attrName, attributes
1148: .getProperty(attrName));
1149: }
1150: return "";
1151: }
1152:
1153: // Modifications
1154:
1155: /**
1156: * Processes a modification tag containing changes to properties of an inherited field/reference/collection.
1157: *
1158: * @param template The template
1159: * @param attributes The attributes of the tag
1160: * @exception XDocletException If an error occurs
1161: * @doc.tag type="content"
1162: * @doc.param name="attributes" optional="true" description="Attributes of the field as name-value pairs 'name=value',
1163: * separated by commas"
1164: * @doc.param name="autoincrement" optional="true" description="Whether the field is
1165: * auto-incremented" values="true,false"
1166: * @doc.param name="auto-delete" optional="true" description="Whether to automatically delete the
1167: * referenced object/the collection on object deletion"
1168: * @doc.param name="auto-retrieve" optional="true" description="Whether to automatically retrieve
1169: * the referenced object/the collection"
1170: * @doc.param name="auto-update" optional="true" description="Whether to automatically update the
1171: * referenced object/the collection"
1172: * @doc.param name="class-ref" optional="true" description="The fully qualified name of the class
1173: * owning the referenced field"
1174: * @doc.param name="collection-class" optional="true" description="The type of the collection if not a
1175: * java.util type or an array"
1176: * @doc.param name="column" optional="true" description="The column for the field"
1177: * @doc.param name="column-documentation" optional="true" description="Documentation on the column"
1178: * @doc.param name="conversion" optional="true" description="The fully qualified name of the
1179: * conversion for the field"
1180: * @doc.param name="database-foreignkey" optional="true" description="Whether a database foreignkey shall be created"
1181: * values="true,false"
1182: * @doc.param name="default-fetch" optional="true" description="The default-fetch setting"
1183: * values="true,false"
1184: * @doc.param name="documentation" optional="true" description="Documentation on the field"
1185: * @doc.param name="element-class-ref" optional="true" description="The fully qualified name of
1186: * the element type"
1187: * @doc.param name="foreignkey" optional="true" description="The name of the
1188: * foreign key (a column when an indirection table is given)"
1189: * @doc.param name="id" optional="true" description="The position of the field in the class
1190: * descriptor"
1191: * @doc.param name="ignore" optional="true" description="Whether the feature shall be ignored"
1192: * values="true,false"
1193: * @doc.param name="indexed" optional="true" description="Whether the field is indexed"
1194: * values="true,false"
1195: * @doc.param name="jdbc-type" optional="true" description="The jdbc type of the column"
1196: * @doc.param name="length" optional="true" description="The length of the column"
1197: * @doc.param name="locking" optional="true" description="Whether the field supports locking"
1198: * values="true,false"
1199: * @doc.param name="name" optional="false" description="The name of the inherited field, reference or collection"
1200: * @doc.param name="nullable" optional="true" description="Whether the field is nullable"
1201: * values="true,false"
1202: * @doc.param name="precision" optional="true" description="The precision of the column"
1203: * @doc.param name="primarykey" optional="true" description="Whether the field is a primarykey"
1204: * values="true,false"
1205: * @doc.param name="proxy" optional="true" description="Whether to use a proxy for the reference/collection"
1206: * @doc.param name="query-customizer" optional="true" description="The query customizer for the collection"
1207: * @doc.param name="query-customizer-attributes" optional="true" description="Attributes for the query customizer for the collection"
1208: * @doc.param name="refresh" optional="true" description="Whether to automatically refresh the
1209: * reference/collection"
1210: * @doc.param name="scale" optional="true" description="The scale of the column"
1211: * @doc.param name="sequence-name" optional="true" description="The name of the sequence for
1212: * incrementing the field"
1213: * @doc.param name="table" optional="true" description="The table of the field (not implemented
1214: * yet)"
1215: */
1216: public String processModification(Properties attributes)
1217: throws XDocletException {
1218: String name = attributes.getProperty(ATTRIBUTE_NAME);
1219: Properties mods = _curClassDef.getModification(name);
1220: String key;
1221: String value;
1222:
1223: if (mods == null) {
1224: mods = new Properties();
1225: _curClassDef.addModification(name, mods);
1226: }
1227:
1228: attributes.remove(ATTRIBUTE_NAME);
1229: for (Enumeration en = attributes.keys(); en.hasMoreElements();) {
1230: key = (String) en.nextElement();
1231: value = attributes.getProperty(key);
1232: mods.setProperty(key, value);
1233: }
1234: return "";
1235: }
1236:
1237: /**
1238: * Processes a modification tag containing changes to properties of an nested field/reference/collection.
1239: *
1240: * @param template The template
1241: * @param attributes The attributes of the tag
1242: * @exception XDocletException If an error occurs
1243: * @doc.tag type="content"
1244: * @doc.param name="attributes" optional="true" description="Attributes of the field as name-value pairs 'name=value',
1245: * separated by commas"
1246: * @doc.param name="autoincrement" optional="true" description="Whether the field is
1247: * auto-incremented" values="true,false"
1248: * @doc.param name="auto-delete" optional="true" description="Whether to automatically delete the
1249: * referenced object/the collection on object deletion"
1250: * @doc.param name="auto-retrieve" optional="true" description="Whether to automatically retrieve
1251: * the referenced object/the collection"
1252: * @doc.param name="auto-update" optional="true" description="Whether to automatically update the
1253: * referenced object/the collection"
1254: * @doc.param name="class-ref" optional="true" description="The fully qualified name of the class
1255: * owning the referenced field"
1256: * @doc.param name="collection-class" optional="true" description="The type of the collection if not a
1257: * java.util type or an array"
1258: * @doc.param name="column" optional="true" description="The column for the field"
1259: * @doc.param name="column-documentation" optional="true" description="Documentation on the column"
1260: * @doc.param name="conversion" optional="true" description="The fully qualified name of the
1261: * conversion for the field"
1262: * @doc.param name="database-foreignkey" optional="true" description="Whether a database foreignkey shall be created"
1263: * values="true,false"
1264: * @doc.param name="default-fetch" optional="true" description="The default-fetch setting"
1265: * values="true,false"
1266: * @doc.param name="documentation" optional="true" description="Documentation on the field"
1267: * @doc.param name="element-class-ref" optional="true" description="The fully qualified name of
1268: * the element type"
1269: * @doc.param name="foreignkey" optional="true" description="The name of the
1270: * foreign key (a column when an indirection table is given)"
1271: * @doc.param name="id" optional="true" description="The position of the field in the class
1272: * descriptor"
1273: * @doc.param name="ignore" optional="true" description="Whether the feature shall be ignored"
1274: * values="true,false"
1275: * @doc.param name="indexed" optional="true" description="Whether the field is indexed"
1276: * values="true,false"
1277: * @doc.param name="jdbc-type" optional="true" description="The jdbc type of the column"
1278: * @doc.param name="length" optional="true" description="The length of the column"
1279: * @doc.param name="locking" optional="true" description="Whether the field supports locking"
1280: * values="true,false"
1281: * @doc.param name="name" optional="false" description="The name of the inherited field, reference or collection"
1282: * @doc.param name="nullable" optional="true" description="Whether the field is nullable"
1283: * values="true,false"
1284: * @doc.param name="precision" optional="true" description="The precision of the column"
1285: * @doc.param name="primarykey" optional="true" description="Whether the field is a primarykey"
1286: * values="true,false"
1287: * @doc.param name="proxy" optional="true" description="Whether to use a proxy for the reference/collection"
1288: * @doc.param name="query-customizer" optional="true" description="The query customizer for the collection"
1289: * @doc.param name="query-customizer-attributes" optional="true" description="Attributes for the query customizer for the collection"
1290: * @doc.param name="refresh" optional="true" description="Whether to automatically refresh the
1291: * reference/collection"
1292: * @doc.param name="scale" optional="true" description="The scale of the column"
1293: * @doc.param name="sequence-name" optional="true" description="The name of the sequence for
1294: * incrementing the field"
1295: * @doc.param name="table" optional="true" description="The table of the field (not implemented
1296: * yet)"
1297: */
1298: public String processNestedModification(Properties attributes)
1299: throws XDocletException {
1300: String prefix = OjbMemberTagsHandler.getMemberName() + "::";
1301: String name = prefix + attributes.getProperty(ATTRIBUTE_NAME);
1302: Properties mods = _curClassDef.getModification(name);
1303: String key;
1304: String value;
1305:
1306: if (mods == null) {
1307: mods = new Properties();
1308: _curClassDef.addModification(name, mods);
1309: }
1310:
1311: attributes.remove(ATTRIBUTE_NAME);
1312: for (Enumeration en = attributes.keys(); en.hasMoreElements();) {
1313: key = (String) en.nextElement();
1314: value = attributes.getProperty(key);
1315: mods.setProperty(key, value);
1316: }
1317: return "";
1318: }
1319:
1320: // Table related
1321:
1322: /**
1323: * Generates a torque schema for the model.
1324: *
1325: * @param attributes The attributes of the tag
1326: * @return The property value
1327: * @exception XDocletException If an error occurs
1328: * @doc.tag type="content"
1329: */
1330: public String createTorqueSchema(Properties attributes)
1331: throws XDocletException {
1332: String dbName = (String) getDocletContext().getConfigParam(
1333: CONFIG_PARAM_DATABASENAME);
1334:
1335: _torqueModel = new TorqueModelDef(dbName, _model);
1336: return "";
1337: }
1338:
1339: /**
1340: * Processes the template for all table definitions in the torque model.
1341: *
1342: * @param template The template
1343: * @param attributes The attributes of the tag
1344: * @exception XDocletException if an error occurs
1345: * @doc.tag type="block"
1346: */
1347: public void forAllTables(String template, Properties attributes)
1348: throws XDocletException {
1349: for (Iterator it = _torqueModel.getTables(); it.hasNext();) {
1350: _curTableDef = (TableDef) it.next();
1351: generate(template);
1352: }
1353: _curTableDef = null;
1354: }
1355:
1356: /**
1357: * Processes the template for all column definitions of the current table.
1358: *
1359: * @param template The template
1360: * @param attributes The attributes of the tag
1361: * @exception XDocletException if an error occurs
1362: * @doc.tag type="block"
1363: */
1364: public void forAllColumns(String template, Properties attributes)
1365: throws XDocletException {
1366: for (Iterator it = _curTableDef.getColumns(); it.hasNext();) {
1367: _curColumnDef = (ColumnDef) it.next();
1368: generate(template);
1369: }
1370: _curColumnDef = null;
1371: }
1372:
1373: /**
1374: * Processes the template for all foreignkeys of the current table.
1375: *
1376: * @param template The template
1377: * @param attributes The attributes of the tag
1378: * @exception XDocletException if an error occurs
1379: * @doc.tag type="block"
1380: */
1381: public void forAllForeignkeys(String template, Properties attributes)
1382: throws XDocletException {
1383: for (Iterator it = _curTableDef.getForeignkeys(); it.hasNext();) {
1384: _curForeignkeyDef = (ForeignkeyDef) it.next();
1385: generate(template);
1386: }
1387: _curForeignkeyDef = null;
1388: }
1389:
1390: /**
1391: * Processes the template for all column pairs of the current foreignkey.
1392: *
1393: * @param template The template
1394: * @param attributes The attributes of the tag
1395: * @exception XDocletException if an error occurs
1396: * @doc.tag type="block"
1397: */
1398: public void forAllForeignkeyColumnPairs(String template,
1399: Properties attributes) throws XDocletException {
1400: for (int idx = 0; idx < _curForeignkeyDef.getNumColumnPairs(); idx++) {
1401: _curPairLeft = _curForeignkeyDef.getLocalColumn(idx);
1402: _curPairRight = _curForeignkeyDef.getRemoteColumn(idx);
1403: generate(template);
1404: }
1405: _curPairLeft = null;
1406: _curPairRight = null;
1407: }
1408:
1409: /**
1410: * Processes the template for all indices of the current table.
1411: *
1412: * @param template The template
1413: * @param attributes The attributes of the tag
1414: * @exception XDocletException if an error occurs
1415: * @doc.tag type="block"
1416: * @doc.param name="unique" optional="true" description="Whether to process the unique indices or not"
1417: * values="true,false"
1418: */
1419: public void forAllIndices(String template, Properties attributes)
1420: throws XDocletException {
1421: boolean processUnique = TypeConversionUtil.stringToBoolean(
1422: attributes.getProperty(ATTRIBUTE_UNIQUE), false);
1423:
1424: // first the default index
1425: _curIndexDef = _curTableDef.getIndex(null);
1426: if ((_curIndexDef != null)
1427: && (processUnique == _curIndexDef.isUnique())) {
1428: generate(template);
1429: }
1430: for (Iterator it = _curTableDef.getIndices(); it.hasNext();) {
1431: _curIndexDef = (IndexDef) it.next();
1432: if (!_curIndexDef.isDefault()
1433: && (processUnique == _curIndexDef.isUnique())) {
1434: generate(template);
1435: }
1436: }
1437: _curIndexDef = null;
1438: }
1439:
1440: /**
1441: * Processes the template for all columns of the current table index.
1442: *
1443: * @param template The template
1444: * @param attributes The attributes of the tag
1445: * @exception XDocletException if an error occurs
1446: * @doc.tag type="block"
1447: */
1448: public void forAllIndexColumns(String template,
1449: Properties attributes) throws XDocletException {
1450: for (Iterator it = _curIndexDef.getColumns(); it.hasNext();) {
1451: _curColumnDef = _curTableDef.getColumn((String) it.next());
1452: generate(template);
1453: }
1454: _curColumnDef = null;
1455: }
1456:
1457: // Other
1458:
1459: /**
1460: * Returns the name of the current object on the specified level.
1461: *
1462: * @param attributes The attributes of the tag
1463: * @return The property value
1464: * @exception XDocletException If an error occurs
1465: * @doc.tag type="content"
1466: * @doc.param name="level" optional="false" description="The level for the current object"
1467: * values="class,field,reference,collection"
1468: */
1469: public String name(Properties attributes) throws XDocletException {
1470: return getDefForLevel(attributes.getProperty(ATTRIBUTE_LEVEL))
1471: .getName();
1472: }
1473:
1474: /**
1475: * Processes the template if the current object on the specified level has a non-empty name.
1476: *
1477: * @param attributes The attributes of the tag
1478: * @return The property value
1479: * @exception XDocletException If an error occurs
1480: * @doc.tag type="block"
1481: * @doc.param name="level" optional="false" description="The level for the current object"
1482: * values="class,field,reference,collection"
1483: */
1484: public void ifHasName(String template, Properties attributes)
1485: throws XDocletException {
1486: String name = getDefForLevel(
1487: attributes.getProperty(ATTRIBUTE_LEVEL)).getName();
1488:
1489: if ((name != null) && (name.length() > 0)) {
1490: generate(template);
1491: }
1492: }
1493:
1494: /**
1495: * Determines whether the current object on the specified level has a specific property, and if so, processes the
1496: * template
1497: *
1498: * @param template The template
1499: * @param attributes The attributes of the tag
1500: * @exception XDocletException If an error occurs
1501: * @doc.tag type="block"
1502: * @doc.param name="level" optional="false" description="The level for the current object"
1503: * values="class,field,reference,collection"
1504: * @doc.param name="name" optional="false" description="The name of the property"
1505: */
1506: public void ifHasProperty(String template, Properties attributes)
1507: throws XDocletException {
1508: String value = getPropertyValue(attributes
1509: .getProperty(ATTRIBUTE_LEVEL), attributes
1510: .getProperty(ATTRIBUTE_NAME));
1511:
1512: if (value != null) {
1513: generate(template);
1514: }
1515: }
1516:
1517: /**
1518: * Determines whether the current object on the specified level does not have a specific property, and if so,
1519: * processes the template
1520: *
1521: * @param template The template
1522: * @param attributes The attributes of the tag
1523: * @exception XDocletException If an error occurs
1524: * @doc.tag type="block"
1525: * @doc.param name="level" optional="false" description="The level for the current object"
1526: * values="class,field,reference,collection"
1527: * @doc.param name="name" optional="false" description="The name of the property"
1528: */
1529: public void ifDoesntHaveProperty(String template,
1530: Properties attributes) throws XDocletException {
1531: String value = getPropertyValue(attributes
1532: .getProperty(ATTRIBUTE_LEVEL), attributes
1533: .getProperty(ATTRIBUTE_NAME));
1534:
1535: if (value == null) {
1536: generate(template);
1537: }
1538: }
1539:
1540: /**
1541: * Returns the value of a property of the current object on the specified level.
1542: *
1543: * @param attributes The attributes of the tag
1544: * @return The property value
1545: * @exception XDocletException If an error occurs
1546: * @doc.tag type="content"
1547: * @doc.param name="level" optional="false" description="The level for the current object"
1548: * values="class,field,reference,collection"
1549: * @doc.param name="name" optional="false" description="The name of the property"
1550: * @doc.param name="default" optional="true" description="A default value to use if the property
1551: * is not defined"
1552: */
1553: public String propertyValue(Properties attributes)
1554: throws XDocletException {
1555: String value = getPropertyValue(attributes
1556: .getProperty(ATTRIBUTE_LEVEL), attributes
1557: .getProperty(ATTRIBUTE_NAME));
1558:
1559: if (value == null) {
1560: value = attributes.getProperty(ATTRIBUTE_DEFAULT);
1561: }
1562: return value;
1563: }
1564:
1565: /**
1566: * Processes the template if the property value of the current object on the specified level equals the given value.
1567: *
1568: * @param template The template
1569: * @param attributes The attributes of the tag
1570: * @exception XDocletException If an error occurs
1571: * @doc.tag type="block"
1572: * @doc.param name="level" optional="false" description="The level for the current object"
1573: * values="class,field,reference,collection"
1574: * @doc.param name="name" optional="false" description="The name of the property"
1575: * @doc.param name="value" optional="false" description="The value to check for"
1576: * @doc.param name="default" optional="true" description="A default value to use if the property
1577: * is not defined"
1578: */
1579: public void ifPropertyValueEquals(String template,
1580: Properties attributes) throws XDocletException {
1581: String value = getPropertyValue(attributes
1582: .getProperty(ATTRIBUTE_LEVEL), attributes
1583: .getProperty(ATTRIBUTE_NAME));
1584: String expected = attributes.getProperty(ATTRIBUTE_VALUE);
1585:
1586: if (value == null) {
1587: value = attributes.getProperty(ATTRIBUTE_DEFAULT);
1588: }
1589: if (expected.equals(value)) {
1590: generate(template);
1591: }
1592: }
1593:
1594: /**
1595: * Processes the template if the property value of the current object on the specified level does not equal the given value.
1596: *
1597: * @param template The template
1598: * @param attributes The attributes of the tag
1599: * @exception XDocletException If an error occurs
1600: * @doc.tag type="block"
1601: * @doc.param name="level" optional="false" description="The level for the current object"
1602: * values="class,field,reference,collection"
1603: * @doc.param name="name" optional="false" description="The name of the property"
1604: * @doc.param name="value" optional="false" description="The value to check for"
1605: * @doc.param name="default" optional="true" description="A default value to use if the property
1606: * is not defined"
1607: */
1608: public void ifPropertyValueDoesntEqual(String template,
1609: Properties attributes) throws XDocletException {
1610: String value = getPropertyValue(attributes
1611: .getProperty(ATTRIBUTE_LEVEL), attributes
1612: .getProperty(ATTRIBUTE_NAME));
1613: String expected = attributes.getProperty(ATTRIBUTE_VALUE);
1614:
1615: if (value == null) {
1616: value = attributes.getProperty(ATTRIBUTE_DEFAULT);
1617: }
1618: if (!expected.equals(value)) {
1619: generate(template);
1620: }
1621: }
1622:
1623: /**
1624: * Processes the template for the comma-separated value pairs in an attribute of the current object on the specified level.
1625: *
1626: * @param template The template
1627: * @param attributes The attributes of the tag
1628: * @exception XDocletException if an error occurs
1629: * @doc.tag type="block"
1630: * @doc.param name="level" optional="false" description="The level for the current object"
1631: * values="class,field,reference,collection"
1632: * @doc.param name="name" optional="true" description="The name of the attribute containg attributes (defaults to 'attributes')"
1633: * @doc.param name="default-right" optional="true" description="The default right value if none is given (defaults to empty value)"
1634: */
1635: public void forAllValuePairs(String template, Properties attributes)
1636: throws XDocletException {
1637: String name = attributes.getProperty(ATTRIBUTE_NAME,
1638: "attributes");
1639: String defaultValue = attributes.getProperty(
1640: ATTRIBUTE_DEFAULT_RIGHT, "");
1641: String attributePairs = getPropertyValue(attributes
1642: .getProperty(ATTRIBUTE_LEVEL), name);
1643:
1644: if ((attributePairs == null) || (attributePairs.length() == 0)) {
1645: return;
1646: }
1647:
1648: String token;
1649: int pos;
1650:
1651: for (CommaListIterator it = new CommaListIterator(
1652: attributePairs); it.hasNext();) {
1653: token = it.getNext();
1654: pos = token.indexOf('=');
1655: if (pos >= 0) {
1656: _curPairLeft = token.substring(0, pos);
1657: _curPairRight = (pos < token.length() - 1 ? token
1658: .substring(pos + 1) : defaultValue);
1659: } else {
1660: _curPairLeft = token;
1661: _curPairRight = defaultValue;
1662: }
1663: if (_curPairLeft.length() > 0) {
1664: generate(template);
1665: }
1666: }
1667: _curPairLeft = null;
1668: _curPairRight = null;
1669: }
1670:
1671: /**
1672: * Returns the left part of the current pair.
1673: *
1674: * @param attributes The attributes of the tag
1675: * @return The property value
1676: * @exception XDocletException If an error occurs
1677: * @doc.tag type="content"
1678: */
1679: public String pairLeft(Properties attributes)
1680: throws XDocletException {
1681: return _curPairLeft;
1682: }
1683:
1684: /**
1685: * Returns the right part of the current pair.
1686: *
1687: * @param attributes The attributes of the tag
1688: * @return The property value
1689: * @exception XDocletException If an error occurs
1690: * @doc.tag type="content"
1691: */
1692: public String pairRight(Properties attributes)
1693: throws XDocletException {
1694: return _curPairRight;
1695: }
1696:
1697: //
1698: // Helper methods
1699: //
1700:
1701: // Class-related and Modification-related
1702:
1703: /**
1704: * Makes sure that there is a class definition for the given qualified name, and returns it.
1705: *
1706: * @param original The XDoclet class object
1707: * @return The class definition
1708: */
1709: private ClassDescriptorDef ensureClassDef(XClass original) {
1710: String name = original.getQualifiedName();
1711: ClassDescriptorDef classDef = _model.getClass(name);
1712:
1713: if (classDef == null) {
1714: classDef = new ClassDescriptorDef(original);
1715: _model.addClass(classDef);
1716: }
1717: return classDef;
1718: }
1719:
1720: /**
1721: * Adds all direct subtypes to the given list.
1722: *
1723: * @param type The type for which to determine the direct subtypes
1724: * @param subTypes The list to receive the subtypes
1725: */
1726: private void addDirectSubTypes(XClass type, ArrayList subTypes) {
1727: if (type.isInterface()) {
1728: if (type.getExtendingInterfaces() != null) {
1729: subTypes.addAll(type.getExtendingInterfaces());
1730: }
1731: // we have to traverse the implementing classes as these array contains all classes that
1732: // implement the interface, not only those who have an "implement" declaration
1733: // note that for whatever reason the declared interfaces are not exported via the XClass interface
1734: // so we have to get them via the underlying class which is hopefully a subclass of AbstractClass
1735: if (type.getImplementingClasses() != null) {
1736: Collection declaredInterfaces = null;
1737: XClass subType;
1738:
1739: for (Iterator it = type.getImplementingClasses()
1740: .iterator(); it.hasNext();) {
1741: subType = (XClass) it.next();
1742: if (subType instanceof AbstractClass) {
1743: declaredInterfaces = ((AbstractClass) subType)
1744: .getDeclaredInterfaces();
1745: if ((declaredInterfaces != null)
1746: && declaredInterfaces.contains(type)) {
1747: subTypes.add(subType);
1748: }
1749: } else {
1750: // Otherwise we have to live with the bug
1751: subTypes.add(subType);
1752: }
1753: }
1754: }
1755: } else {
1756: subTypes.addAll(type.getDirectSubclasses());
1757: }
1758: }
1759:
1760: // Field-related
1761:
1762: /**
1763: * Determines the default mapping for the type of the current member. If the current member is a field, the type of
1764: * the field is used. If the current member is an accessor, then the return type (get/is) or parameter type (set) is
1765: * used.
1766: *
1767: * @return The jdbc type
1768: * @exception XDocletException If an error occurs
1769: */
1770: public static String getDefaultJdbcTypeForCurrentMember()
1771: throws XDocletException {
1772: if (OjbMemberTagsHandler.getMemberDimension() > 0) {
1773: return JdbcTypeHelper.JDBC_DEFAULT_TYPE_FOR_ARRAY;
1774: }
1775:
1776: String type = OjbMemberTagsHandler.getMemberType()
1777: .getQualifiedName();
1778:
1779: return JdbcTypeHelper.getDefaultJdbcTypeFor(type);
1780: }
1781:
1782: /**
1783: * Determines the default conversion for the type of the current member. If the current member is a field, the type of
1784: * the field is used. If the current member is an accessor, then the return type (get/is) or parameter type (set) is
1785: * used.
1786: *
1787: * @return The jdbc type
1788: * @exception XDocletException If an error occurs
1789: */
1790: private static String getDefaultJdbcConversionForCurrentMember()
1791: throws XDocletException {
1792: if (OjbMemberTagsHandler.getMemberDimension() > 0) {
1793: return JdbcTypeHelper.JDBC_DEFAULT_CONVERSION;
1794: }
1795:
1796: String type = OjbMemberTagsHandler.getMemberType()
1797: .getQualifiedName();
1798:
1799: return JdbcTypeHelper.getDefaultConversionFor(type);
1800: }
1801:
1802: /**
1803: * Searches the type and its sub types for the nearest ojb-persistent type and returns its name.
1804: *
1805: * @param type The type to search
1806: * @return The qualified name of the found type or <code>null</code> if no type has been found
1807: */
1808: private String searchForPersistentSubType(XClass type) {
1809: ArrayList queue = new ArrayList();
1810: XClass subType;
1811:
1812: queue.add(type);
1813: while (!queue.isEmpty()) {
1814: subType = (XClass) queue.get(0);
1815: queue.remove(0);
1816: if (_model.hasClass(subType.getQualifiedName())) {
1817: return subType.getQualifiedName();
1818: }
1819: addDirectSubTypes(subType, queue);
1820: }
1821: return null;
1822: }
1823:
1824: /**
1825: * Returns the current definition on the indicated level.
1826: *
1827: * @param level The level
1828: * @return The definition
1829: */
1830: private DefBase getDefForLevel(String level) {
1831: if (LEVEL_CLASS.equals(level)) {
1832: return _curClassDef;
1833: } else if (LEVEL_FIELD.equals(level)) {
1834: return _curFieldDef;
1835: } else if (LEVEL_REFERENCE.equals(level)) {
1836: return _curReferenceDef;
1837: } else if (LEVEL_COLLECTION.equals(level)) {
1838: return _curCollectionDef;
1839: } else if (LEVEL_OBJECT_CACHE.equals(level)) {
1840: return _curObjectCacheDef;
1841: } else if (LEVEL_INDEX_DESC.equals(level)) {
1842: return _curIndexDescriptorDef;
1843: } else if (LEVEL_TABLE.equals(level)) {
1844: return _curTableDef;
1845: } else if (LEVEL_COLUMN.equals(level)) {
1846: return _curColumnDef;
1847: } else if (LEVEL_FOREIGNKEY.equals(level)) {
1848: return _curForeignkeyDef;
1849: } else if (LEVEL_INDEX.equals(level)) {
1850: return _curIndexDef;
1851: } else if (LEVEL_PROCEDURE.equals(level)) {
1852: return _curProcedureDef;
1853: } else if (LEVEL_PROCEDURE_ARGUMENT.equals(level)) {
1854: return _curProcedureArgumentDef;
1855: } else {
1856: return null;
1857: }
1858: }
1859:
1860: /**
1861: * Determines whether the current feature on the given level is ignored.
1862: *
1863: * @param level The level
1864: * @return <code>true</code> if this feature is ignored
1865: */
1866: private boolean isFeatureIgnored(String level) {
1867: return getDefForLevel(level).getBooleanProperty(
1868: PropertyHelper.OJB_PROPERTY_IGNORE, false);
1869: }
1870:
1871: /**
1872: * Returns the value of the indicated property of the current object on the specified level.
1873: *
1874: * @param level The level
1875: * @param name The name of the property
1876: * @return The property value
1877: */
1878: private String getPropertyValue(String level, String name) {
1879: return getDefForLevel(level).getProperty(name);
1880: }
1881:
1882: }
|