Source Code Cross Referenced for SequenceManagerHelper.java in  » Database-ORM » db-ojb » org » apache » ojb » broker » util » sequence » 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 » org.apache.ojb.broker.util.sequence 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.ojb.broker.util.sequence;
002:
003:        /* Copyright 2002-2005 The Apache Software Foundation
004:         *
005:         * Licensed under the Apache License, Version 2.0 (the "License");
006:         * you may not use this file except in compliance with the License.
007:         * You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        import java.sql.ResultSet;
019:        import java.sql.Statement;
020:        import java.util.Collection;
021:        import java.util.Iterator;
022:        import java.util.Properties;
023:        import java.util.Vector;
024:
025:        import org.apache.ojb.broker.PersistenceBroker;
026:        import org.apache.ojb.broker.PersistenceBrokerException;
027:        import org.apache.ojb.broker.accesslayer.StatementManagerIF;
028:        import org.apache.ojb.broker.metadata.ClassDescriptor;
029:        import org.apache.ojb.broker.metadata.FieldDescriptor;
030:        import org.apache.ojb.broker.query.Query;
031:        import org.apache.ojb.broker.util.logging.Logger;
032:        import org.apache.ojb.broker.util.logging.LoggerFactory;
033:
034:        /**
035:         * Helper class for SequenceManager implementations.
036:         *
037:         * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
038:         * @version $Id: SequenceManagerHelper.java,v 1.17.2.8 2005/12/21 22:28:41 tomdz Exp $
039:         */
040:        public class SequenceManagerHelper {
041:            private static Logger log = LoggerFactory
042:                    .getLogger(SequenceManagerHelper.class);
043:
044:            /**
045:             * Property name used to configure sequence manager implementations.
046:             */
047:            public static final String PROP_SEQ_AS = "seq.as";
048:            /**
049:             * Property name used to configure sequence manager implementations.
050:             * @deprecated use {@link #PROP_SEQ_START} instead.
051:             */
052:            public static final String PROP_SEQ_START_OLD = "sequenceStart";
053:            /**
054:             * Property name used to configure sequence manager implementations.
055:             */
056:            public static final String PROP_SEQ_START = "seq.start";
057:            /**
058:             * Property name used to configure sequence manager implementations.
059:             */
060:            public static final String PROP_SEQ_INCREMENT_BY = "seq.incrementBy";
061:            /**
062:             * Property name used to configure sequence manager implementations.
063:             */
064:            public static final String PROP_SEQ_MAX_VALUE = "seq.maxValue";
065:            /**
066:             * Property name used to configure sequence manager implementations.
067:             */
068:            public static final String PROP_SEQ_MIN_VALUE = "seq.minValue";
069:            /**
070:             * Property name used to configure sequence manager implementations.
071:             */
072:            public static final String PROP_SEQ_CYCLE = "seq.cycle";
073:            /**
074:             * Property name used to configure sequence manager implementations.
075:             */
076:            public static final String PROP_SEQ_CACHE = "seq.cache";
077:            /**
078:             * Property name used to configure sequence manager implementations.
079:             */
080:            public static final String PROP_SEQ_ORDER = "seq.order";
081:
082:            private static final String SEQ_PREFIX = "SEQ_";
083:            private static final String SEQ_UNASSIGNED = "UNASSIGNED";
084:            private static final String SM_SELECT_MAX = "SELECT MAX(";
085:            private static final String SM_FROM = ") FROM ";
086:
087:            /**
088:             * Prefix for global sequence names.
089:             */
090:
091:            /**
092:             * Returns a unique sequence name (unique across all extents).
093:             * <br/>
094:             * If we found a non null value for the 'sequence-name' attribute in
095:             * the field descriptor, we use the 'sequence-name' value as sequence name.
096:             * <br/>
097:             * Else if the top-level class of the target class has extents,
098:             * we take the first extent class table name of the extents as
099:             * sequence name.
100:             * <br/>
101:             * Else we take the table name of the target class.
102:             * <p>
103:             * If the method argument 'autoNaming' is true, the generated
104:             * sequence name will be set in the given field descriptor
105:             * using {@link org.apache.ojb.broker.metadata.FieldDescriptor#setSequenceName}
106:             * to speed up sequence name lookup in future calls.
107:             * </p>
108:             * @param brokerForClass current used PB instance
109:             * @param field target field
110:             * @param autoNaming if 'false' no auto sequence name was build and
111:             * a exception was throw if none could be found in field.
112:             */
113:            public static String buildSequenceName(
114:                    PersistenceBroker brokerForClass, FieldDescriptor field,
115:                    boolean autoNaming) throws SequenceManagerException {
116:                String seqName = field.getSequenceName();
117:                /*
118:                if we found a sequence name bound to the field descriptor
119:                via 'sequence-name' attribute we use that name
120:                 */
121:                if (seqName != null && seqName.trim().length() != 0) {
122:                    return seqName;
123:                } else if (!autoNaming) {
124:                    /*
125:                    arminw:
126:                    we don't find a sequence name and we should not automatic build one,
127:                    thus we throw an exception
128:                     */
129:                    throw new SequenceManagerException(
130:                            "Could not find sequence-name for field '"
131:                                    + field
132:                                    + "' of class '"
133:                                    + field.getClassDescriptor()
134:                                            .getClassNameOfObject()
135:                                    + "', property 'autoNaming' in sequence-manager element in repository was '"
136:                                    + autoNaming
137:                                    + "'. Set autoNaming true in sequence-descriptor or define a "
138:                                    + " sequence-name in field-descriptor.");
139:                }
140:
141:                ClassDescriptor cldTargetClass = field.getClassDescriptor();
142:                /*
143:                check for inheritance on multiple table
144:                 */
145:                cldTargetClass = findInheritanceRoot(cldTargetClass);
146:                Class topLevel = brokerForClass.getTopLevelClass(cldTargetClass
147:                        .getClassOfObject());
148:                ClassDescriptor cldTopLevel = brokerForClass
149:                        .getClassDescriptor(topLevel);
150:                /**
151:                 *
152:                 * MBAIRD
153:                 * Should not use classname for the sequenceName as we will end up
154:                 * re-using sequence numbers for classes mapped to the same table.
155:                 * Instead, make the FullTableName the discriminator since it will
156:                 * always be unique for that table, and hence that class.
157:                 *
158:                 * arminw:
159:                 * If the found top-level class has extents, we take the first
160:                 * found extent class table name as sequence name. Else we take
161:                 * the table name of the 'targetClass'.
162:                 *
163:                 */
164:                if (cldTopLevel.isExtent()) {
165:                    /*
166:                    arminw:
167:                    this is a little critical, because we do not know if the extent classes
168:                    will change by and by and the first found extent class may change, thus the
169:                    returned table name could change!
170:                    But I don't know a way to resolve this problem. I put a comment to the
171:                    sequence manager docs
172:                    TODO: find better solution
173:                     */
174:                    //            seqName = brokerForClass.getClassDescriptor(((Class) cldTopLevel.getExtentClasses().
175:                    //                    get(0))).getFullTableName();
176:                    seqName = firstFoundTableName(brokerForClass, cldTopLevel);
177:                } else {
178:                    seqName = cldTargetClass.getFullTableName();
179:                }
180:                //        log.info("* targetClass: "+targetClass +", toplevel: "+topLevel+ " seqName: "+seqName);
181:                if (seqName == null) {
182:                    seqName = SEQ_UNASSIGNED;
183:                    log
184:                            .warn("Too complex structure, can not assign automatic sequence name for field '"
185:                                    + field.getAttributeName()
186:                                    + "' in class '"
187:                                    + field.getClassDescriptor()
188:                                            .getClassNameOfObject()
189:                                    + "'. Use a default sequence name instead: "
190:                                    + (SEQ_PREFIX + seqName));
191:                }
192:                //        System.out.println("* targetClass: " + cldTargetClass.getClassNameOfObject() + ", toplevel: " + topLevel + " seqName: " + seqName);
193:                seqName = SEQ_PREFIX + seqName;
194:                if (log.isDebugEnabled())
195:                    log
196:                            .debug("Set automatic generated sequence-name for field '"
197:                                    + field.getAttributeName()
198:                                    + "' in class '"
199:                                    + field.getClassDescriptor()
200:                                            .getClassNameOfObject() + "'.");
201:                field.setSequenceName(seqName);
202:                return seqName;
203:            }
204:
205:            /**
206:             * Returns the root {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the inheriatance
207:             * hierachy of the given descriptor or the descriptor itself if no inheriatance on multiple table is
208:             * used.
209:             */
210:            private static ClassDescriptor findInheritanceRoot(
211:                    ClassDescriptor cld) {
212:                ClassDescriptor result = cld;
213:                if (cld.getSuperClassDescriptor() != null) {
214:                    result = findInheritanceRoot(cld.getSuperClassDescriptor());
215:                }
216:                return result;
217:            }
218:
219:            /**
220:             * try to find the first none null table name for the given class-descriptor.
221:             * If cld has extent classes, all of these cld's searched for the first none null
222:             * table name.
223:             */
224:            private static String firstFoundTableName(
225:                    PersistenceBroker brokerForClass, ClassDescriptor cld) {
226:                String name = null;
227:                if (!cld.isInterface() && cld.getFullTableName() != null) {
228:                    return cld.getFullTableName();
229:                }
230:                if (cld.isExtent()) {
231:                    Collection extentClasses = cld.getExtentClasses();
232:                    for (Iterator iterator = extentClasses.iterator(); iterator
233:                            .hasNext();) {
234:                        name = firstFoundTableName(brokerForClass,
235:                                brokerForClass
236:                                        .getClassDescriptor((Class) iterator
237:                                                .next()));
238:                        // System.out.println("## " + cld.getClassNameOfObject()+" - name: "+name);
239:                        if (name != null)
240:                            break;
241:                    }
242:                }
243:                return name;
244:            }
245:
246:            /**
247:             * Lookup all tables associated with given class (search all extent classes)
248:             * to find the current maximum value for the given field.
249:             * <br><b>Note:</b> Only works for <code>long</code> autoincrement fields.
250:             * @param brokerForClass persistence broker instance match the database of the
251:             * given field/class
252:             * @param field the target field
253:             */
254:            public static long getMaxForExtent(
255:                    PersistenceBroker brokerForClass, FieldDescriptor field)
256:                    throws PersistenceBrokerException {
257:                if (field == null) {
258:                    log
259:                            .error("Given FieldDescriptor was null, could not detect max value across all extents");
260:                    return 0;
261:                    // throw new PersistenceBrokerException("Given FieldDescriptor was null");
262:                }
263:                // first lookup top-level class
264:                Class topLevel = brokerForClass.getTopLevelClass(field
265:                        .getClassDescriptor().getClassOfObject());
266:                return getMaxId(brokerForClass, topLevel, field);
267:            }
268:
269:            /**
270:             * Search down all extent classes and return max of all found
271:             * PK values.
272:             */
273:            public static long getMaxId(PersistenceBroker brokerForClass,
274:                    Class topLevel, FieldDescriptor original)
275:                    throws PersistenceBrokerException {
276:                long max = 0;
277:                long tmp;
278:                ClassDescriptor cld = brokerForClass
279:                        .getClassDescriptor(topLevel);
280:
281:                // if class is not an interface / not abstract we have to search its directly mapped table
282:                if (!cld.isInterface() && !cld.isAbstract()) {
283:                    tmp = getMaxIdForClass(brokerForClass, cld, original);
284:                    if (tmp > max) {
285:                        max = tmp;
286:                    }
287:                }
288:                // if class is an extent we have to search through its subclasses
289:                if (cld.isExtent()) {
290:                    Vector extentClasses = cld.getExtentClasses();
291:                    for (int i = 0; i < extentClasses.size(); i++) {
292:                        Class extentClass = (Class) extentClasses.get(i);
293:                        if (cld.getClassOfObject().equals(extentClass)) {
294:                            throw new PersistenceBrokerException(
295:                                    "Circular extent in " + extentClass
296:                                            + ", please check the repository");
297:                        } else {
298:                            // fix by Mark Rowell
299:                            // Call recursive
300:                            tmp = getMaxId(brokerForClass, extentClass,
301:                                    original);
302:                        }
303:                        if (tmp > max) {
304:                            max = tmp;
305:                        }
306:                    }
307:                }
308:                return max;
309:            }
310:
311:            /**
312:             * lookup current maximum value for a single field in
313:             * table the given class descriptor was associated.
314:             */
315:            public static long getMaxIdForClass(
316:                    PersistenceBroker brokerForClass,
317:                    ClassDescriptor cldForOriginalOrExtent,
318:                    FieldDescriptor original) throws PersistenceBrokerException {
319:                FieldDescriptor field = null;
320:                if (!original.getClassDescriptor().equals(
321:                        cldForOriginalOrExtent)) {
322:                    // check if extent match not the same table
323:                    if (!original.getClassDescriptor().getFullTableName()
324:                            .equals(cldForOriginalOrExtent.getFullTableName())) {
325:                        // we have to look for id's in extent class table
326:                        field = cldForOriginalOrExtent
327:                                .getFieldDescriptorByName(original
328:                                        .getAttributeName());
329:                    }
330:                } else {
331:                    field = original;
332:                }
333:                if (field == null) {
334:                    // if null skip this call
335:                    return 0;
336:                }
337:
338:                String column = field.getColumnName();
339:                long result = 0;
340:                ResultSet rs = null;
341:                Statement stmt = null;
342:                StatementManagerIF sm = brokerForClass
343:                        .serviceStatementManager();
344:                String table = cldForOriginalOrExtent.getFullTableName();
345:                // String column = cld.getFieldDescriptorByName(fieldName).getColumnName();
346:                String sql = SM_SELECT_MAX + column + SM_FROM + table;
347:                try {
348:                    //lookup max id for the current class
349:                    stmt = sm.getGenericStatement(cldForOriginalOrExtent,
350:                            Query.NOT_SCROLLABLE);
351:                    rs = stmt.executeQuery(sql);
352:                    rs.next();
353:                    result = rs.getLong(1);
354:                } catch (Exception e) {
355:                    log.warn("Cannot lookup max value from table "
356:                            + table
357:                            + " for column "
358:                            + column
359:                            + ", PB was "
360:                            + brokerForClass
361:                            + ", using jdbc-descriptor "
362:                            + brokerForClass.serviceConnectionManager()
363:                                    .getConnectionDescriptor(), e);
364:                } finally {
365:                    try {
366:                        sm.closeResources(stmt, rs);
367:                    } catch (Exception ignore) {
368:                        // ignore it
369:                    }
370:                }
371:                return result;
372:            }
373:
374:            /**
375:             * Database sequence properties helper method.
376:             * Return sequence <em>start value</em> or <em>null</em>
377:             * if not set.
378:             *
379:             * @param prop The {@link java.util.Properties} instance to use.
380:             * @return The found expression or <em>null</em>.
381:             */
382:            public static Long getSeqStart(Properties prop) {
383:                String result = prop.getProperty(PROP_SEQ_START, null);
384:                if (result == null) {
385:                    result = prop.getProperty(PROP_SEQ_START_OLD, null);
386:                }
387:                if (result != null) {
388:                    return new Long(Long.parseLong(result));
389:                } else {
390:                    return null;
391:                }
392:            }
393:
394:            /**
395:             * Database sequence properties helper method.
396:             * Return sequence <em>increment by value</em> or <em>null</em>
397:             * if not set.
398:             *
399:             * @param prop The {@link java.util.Properties} instance to use.
400:             * @return The found expression or <em>null</em>.
401:             */
402:            public static Long getSeqIncrementBy(Properties prop) {
403:                String result = prop.getProperty(PROP_SEQ_INCREMENT_BY, null);
404:                if (result != null) {
405:                    return new Long(Long.parseLong(result));
406:                } else {
407:                    return null;
408:                }
409:            }
410:
411:            /**
412:             * Database sequence properties helper method.
413:             * Return sequence <em>max value</em> or <em>null</em>
414:             * if not set.
415:             *
416:             * @param prop The {@link java.util.Properties} instance to use.
417:             * @return The found expression or <em>null</em>.
418:             */
419:            public static Long getSeqMaxValue(Properties prop) {
420:                String result = prop.getProperty(PROP_SEQ_MAX_VALUE, null);
421:                if (result != null) {
422:                    return new Long(Long.parseLong(result));
423:                } else {
424:                    return null;
425:                }
426:            }
427:
428:            /**
429:             * Database sequence properties helper method.
430:             * Return sequence <em>min value</em> or <em>null</em>
431:             * if not set.
432:             *
433:             * @param prop The {@link java.util.Properties} instance to use.
434:             * @return The found expression or <em>null</em>.
435:             */
436:            public static Long getSeqMinValue(Properties prop) {
437:                String result = prop.getProperty(PROP_SEQ_MIN_VALUE, null);
438:                if (result != null) {
439:                    return new Long(Long.parseLong(result));
440:                } else {
441:                    return null;
442:                }
443:            }
444:
445:            /**
446:             * Database sequence properties helper method.
447:             * Return sequence <em>cache value</em> or <em>null</em>
448:             * if not set.
449:             *
450:             * @param prop The {@link java.util.Properties} instance to use.
451:             * @return The found expression or <em>null</em>.
452:             */
453:            public static Long getSeqCacheValue(Properties prop) {
454:                String result = prop.getProperty(PROP_SEQ_CACHE, null);
455:                if (result != null) {
456:                    return new Long(Long.parseLong(result));
457:                } else {
458:                    return null;
459:                }
460:            }
461:
462:            /**
463:             * Database sequence properties helper method.
464:             * Return sequence <em>cycle</em> Booelan or <em>null</em>
465:             * if not set.
466:             *
467:             * @param prop The {@link java.util.Properties} instance to use.
468:             * @return The found expression or <em>null</em>.
469:             */
470:            public static Boolean getSeqCycleValue(Properties prop) {
471:                String result = prop.getProperty(PROP_SEQ_CYCLE, null);
472:                if (result != null) {
473:                    return Boolean.valueOf(result);
474:                } else {
475:                    return null;
476:                }
477:            }
478:
479:            /**
480:             * Database sequence properties helper method.
481:             * Return sequence <em>order</em> Booelan or <em>null</em>
482:             * if not set.
483:             *
484:             * @param prop The {@link java.util.Properties} instance to use.
485:             * @return The found expression or <em>null</em>.
486:             */
487:            public static Boolean getSeqOrderValue(Properties prop) {
488:                String result = prop.getProperty(PROP_SEQ_ORDER, null);
489:                if (result != null) {
490:                    return Boolean.valueOf(result);
491:                } else {
492:                    return null;
493:                }
494:            }
495:
496:            /**
497:             * Database sequence properties helper method.
498:             * Return the datatype to set for the sequence or <em>null</em>
499:             * if not set.
500:             *
501:             * @param prop The {@link java.util.Properties} instance to use.
502:             * @return The found expression or <em>null</em>.
503:             */
504:            public static String getSeqAsValue(Properties prop) {
505:                return prop.getProperty(PROP_SEQ_AS, null);
506:            }
507:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.