Source Code Cross Referenced for OjbTagsHandler.java in  » Database-ORM » db-ojb » xdoclet » modules » ojb » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » db ojb » xdoclet.modules.ojb 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.