Source Code Cross Referenced for EntityBeanIntrospector.java in  » Testing » Ejb3Unit » com » bm » introspectors » 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 » Testing » Ejb3Unit » com.bm.introspectors 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package com.bm.introspectors;
002:
003:        import java.lang.annotation.Annotation;
004:        import java.lang.reflect.Field;
005:        import java.util.Set;
006:        import java.util.Map.Entry;
007:
008:        import javax.persistence.DiscriminatorColumn;
009:        import javax.persistence.DiscriminatorType;
010:        import javax.persistence.DiscriminatorValue;
011:        import javax.persistence.EmbeddedId;
012:        import javax.persistence.Entity;
013:        import javax.persistence.IdClass;
014:        import javax.persistence.Inheritance;
015:        import javax.persistence.InheritanceType;
016:        import javax.persistence.Table;
017:
018:        import org.apache.log4j.Logger;
019:
020:        import com.bm.introspectors.relations.EntityReleationInfo;
021:        import com.bm.introspectors.relations.GlobalPrimaryKeyStore;
022:        import com.bm.introspectors.relations.ManyToOneReleation;
023:        import com.bm.utils.AccessType;
024:        import com.bm.utils.AccessTypeFinder;
025:        import com.bm.utils.IdClassInstanceGen;
026:
027:        /**
028:         * This class inspects all relevant fields of an entity bean and holds the
029:         * information.
030:         * 
031:         * @author Daniel Wiese
032:         * @author Istvan Devai
033:         * @param <T> -
034:         *            the type of the class to inspect
035:         * @since 07.10.2005
036:         */
037:        public class EntityBeanIntrospector<T> extends
038:                AbstractPersistentClassIntrospector<T> implements 
039:                Introspector<T> {
040:
041:            static final Logger log = Logger
042:                    .getLogger(EntityBeanIntrospector.class);
043:
044:            /** true if the class has an composed pk field. * */
045:            private boolean hasPKClass = false;
046:
047:            /** the introspector for the embedded class. * */
048:            private EmbeddedClassIntrospector<Object> embeddedPKClass = null;
049:
050:            /** the table name. * */
051:            private String tableName;
052:
053:            /** the table name. * */
054:            private String schemaName;
055:
056:            private boolean hasSchema = false;
057:
058:            private Class<?> idClass = null;
059:
060:            private final Class<T> toInspect;
061:
062:            /** the inheritance type used by the entity class (null when no inheritance used) */
063:            private InheritanceType inheritanceStrategy;
064:
065:            /** the name of the discriminator (if a single-table inheritance strategy is used) */
066:            private String discriminatorName;
067:
068:            /** the value of the discriminator for the introspected class (if a single-table inheritance strategy is used) */
069:            private String discriminatorValue;
070:
071:            /** the type of the discriminator (if a single-table inheritance strategy is used) */
072:            private Class discriminatorType;
073:
074:            /**
075:             * Constructor with the class to inspect.
076:             * 
077:             * @param toInspect -
078:             *            the class to inspect
079:             */
080:            public EntityBeanIntrospector(Class<T> toInspect) {
081:
082:                this .toInspect = toInspect;
083:                Annotation[] classAnnotations = toInspect.getAnnotations();
084:                boolean isSessionBean = false;
085:                boolean isTableNameSpecified = false;
086:                boolean isAccessTypeField = false;
087:                Entity entityAnnotation = null;
088:
089:                // iterate over the annotations
090:                for (Annotation a : classAnnotations) {
091:                    if (a instanceof  Entity) {
092:                        log.debug("The class to introspect "
093:                                + toInspect.getCanonicalName()
094:                                + " is an Entity-Bean");
095:                        isSessionBean = true;
096:                        if (AccessTypeFinder.findAccessType(toInspect).equals(
097:                                AccessType.FIELD)) {
098:                            isAccessTypeField = true;
099:                        }
100:
101:                        entityAnnotation = (Entity) a;
102:
103:                    } else if (a instanceof  Table) {
104:                        Table table = (Table) a;
105:                        this .tableName = table.name();
106:                        this .hasSchema = !table.schema().equals("");
107:                        this .schemaName = table.schema();
108:                        isTableNameSpecified = true;
109:                    } else if (a instanceof  IdClass) {
110:                        this .idClass = ((IdClass) a).value();
111:                    }
112:                }
113:
114:                // check for mandatory conditions
115:                if (!isSessionBean) {
116:                    throw new RuntimeException("The class "
117:                            + toInspect.getSimpleName()
118:                            + " is not a entity bean");
119:                }
120:
121:                if (!isTableNameSpecified) {
122:                    this .tableName = this .generateDefautTableName(toInspect,
123:                            entityAnnotation);
124:                    log
125:                            .debug("The class "
126:                                    + toInspect.getSimpleName()
127:                                    + " doas not specify a table name! Uning default Name: "
128:                                    + this .tableName);
129:
130:                }
131:
132:                if (isAccessTypeField) {
133:                    this .processAccessTypeField(toInspect);
134:                } else {
135:                    this .processAccessTypeProperty(toInspect);
136:                }
137:
138:                // Process Entity inheritance annotations (if any)
139:                processInheritance(toInspect);
140:
141:                postProcessRelationProperties();
142:            }
143:
144:            /**
145:             * Overide the abstract implementation of this method, to handle with
146:             * embedded classes
147:             * 
148:             * @author Daniel Wiese
149:             * @since 15.10.2005
150:             * @see com.bm.introspectors.AbstractPersistentClassIntrospector#processAccessTypeField(java.lang.Class)
151:             */
152:            @Override
153:            protected void processAccessTypeField(Class<T> toInspect) {
154:                // class the super method
155:                super .processAccessTypeField(toInspect);
156:                // extract meta information
157:                Field[] fields = toInspect.getDeclaredFields();
158:                for (Field aktField : fields) {
159:                    // don't introspect fields generated by Hibernate
160:                    Annotation[] fieldAnnotations = aktField.getAnnotations();
161:
162:                    // look into the annotations
163:                    for (Annotation a : fieldAnnotations) {
164:                        // set the embedded class, if any
165:                        if (a instanceof  EmbeddedId) {
166:                            this .embeddedPKClass = new EmbeddedClassIntrospector<Object>(
167:                                    new Property(aktField));
168:                            this .hasPKClass = true;
169:
170:                            // set the akt field information
171:                            final Property aktProperty = new Property(aktField);
172:                            if (this .getPresistentFieldInfo(aktProperty) != null) {
173:                                final PersistentPropertyInfo fi = this 
174:                                        .getPresistentFieldInfo(aktProperty);
175:                                fi.setEmbeddedClass(true);
176:                                fi.setNullable(false);
177:                            }
178:
179:                            // set the akt pk information> Ebedded classes are not
180:                            // generated
181:                            PrimaryKeyInfo info = new PrimaryKeyInfo(
182:                                    ((EmbeddedId) a));
183:                            this .extractGenerator(fieldAnnotations, info);
184:                            this .pkFieldInfo.put(aktProperty, info);
185:                        }
186:                    }
187:                }
188:            }
189:
190:            /**
191:             * Returns the pk to delete one entity bean.
192:             * 
193:             * @param entityBean -
194:             *            the entity bean instance
195:             * @return - return the pk or the pk class
196:             */
197:            public Object getPrimaryKey(T entityBean) {
198:                try {
199:                    if (this .hasEmbeddedPKClass()) {
200:                        // return the embedded class instance
201:                        return this .getField(entityBean, this .embeddedPKClass
202:                                .getAttibuteName());
203:                    } else if (this .getPkFields().size() == 1) {
204:                        // return the single element
205:                        Property toRead = this .getPkFields().iterator().next();
206:                        return this .getField(entityBean, toRead);
207:                    } else if (this .getPkFields().size() > 0 && hasIdClass()) {
208:                        IdClassInstanceGen idClassInstanceGen = new IdClassInstanceGen(
209:                                this .getPkFields(), this .idClass, entityBean);
210:                        return idClassInstanceGen.getIDClassIntance();
211:
212:                    } else {
213:                        throw new RuntimeException(
214:                                "Multiple PK fields detected, use EmbeddedPKClass or IDClass");
215:                    }
216:                } catch (IllegalAccessException e) {
217:                    log.error(e);
218:                    throw new RuntimeException(e);
219:                }
220:            }
221:
222:            /**
223:             * Returns the tableName.
224:             * 
225:             * @return Returns the tableName.
226:             */
227:            public String getTableName() {
228:                return tableName;
229:            }
230:
231:            /**
232:             * Returns the tableName.
233:             * 
234:             * @return Returns the tableName.
235:             */
236:            public String getShemaName() {
237:                return this .schemaName;
238:            }
239:
240:            /**
241:             * Returns if a chema name is persent.
242:             * 
243:             * @return a chema name is persent.
244:             */
245:            public boolean hasSchema() {
246:                return this .hasSchema;
247:            }
248:
249:            /**
250:             * Returns the embeddedPKClass.
251:             * 
252:             * @return Returns the embeddedPKClass.
253:             */
254:            public EmbeddedClassIntrospector<Object> getEmbeddedPKClass() {
255:                return embeddedPKClass;
256:            }
257:
258:            /**
259:             * Returns the hasPKClass.
260:             * 
261:             * @return Returns the hasPKClass.
262:             */
263:            public boolean hasEmbeddedPKClass() {
264:                return hasPKClass;
265:            }
266:
267:            /**
268:             * Returns the hasPKClass.
269:             * 
270:             * @return Returns the hasPKClass.
271:             */
272:            public boolean hasIdClass() {
273:                return idClass != null;
274:            }
275:
276:            /**
277:             * If no table name is specifed hgenrate a JSR 220 table name form class
278:             * 
279:             * @param clazz -
280:             *            the clss name
281:             * @return - the JSR 220 default table name
282:             */
283:            private String generateDefautTableName(Class clazz,
284:                    Entity entityAnnotation) {
285:
286:                if (entityAnnotation != null
287:                        && !entityAnnotation.name().equals("")) {
288:                    return entityAnnotation.name().toUpperCase();
289:                }
290:
291:                String back = clazz.getName();
292:                if (back.lastIndexOf(".") > 0
293:                        && back.lastIndexOf(".") + 1 < back.length()) {
294:                    back = back.substring(back.lastIndexOf(".") + 1, back
295:                            .length());
296:                    return back.toUpperCase();
297:                } else {
298:                    return back.toUpperCase();
299:                }
300:            }
301:
302:            /**
303:             * Returns the name of the class to inspect.
304:             */
305:            public String getPersistentClassName() {
306:                return this .toInspect.getName();
307:
308:            }
309:
310:            /**
311:             * Returns the logger for this class.
312:             * @return
313:             */
314:            protected Logger getLogger() {
315:                return log;
316:            }
317:
318:            /**
319:             * Perform post processing on relation properties. Has to be done after the 
320:             * EntityBeanIntrospectors have processed all properties, to avoid cyclic
321:             * dependencies.
322:             */
323:            private void postProcessRelationProperties() {
324:
325:                for (Entry<Property, PersistentPropertyInfo> entry : fieldInfo
326:                        .entrySet()) {
327:                    if (entry.getValue().isReleation()) {
328:                        EntityReleationInfo relation = entry.getValue()
329:                                .getEntityReleationInfo();
330:                        // TODO (Pd): see if we can generalize this, to other relation types
331:                        if (relation instanceof  ManyToOneReleation) {
332:                            Class targetClass = ((ManyToOneReleation) relation)
333:                                    .getTargetClass();
334:                            Set<Property> keyProps = GlobalPrimaryKeyStore
335:                                    .getStore().getPrimaryKeyInfo(targetClass);
336:                            ((ManyToOneReleation) relation)
337:                                    .setTargetKeyProperty(keyProps);
338:                            // Check that database name is set (it's explicitly unset while processing the 
339:                            // ManyToOne annotation, to be able to recognize the case when it's not 
340:                            // specified by a Column annotation)
341:                            if (entry.getValue().getDbName() == null) {
342:                                // Currently, only single key columns are supported
343:                                String keyName = keyProps.iterator().next()
344:                                        .getName();
345:                                String dbName = entry.getKey().getName() + "_"
346:                                        + keyName;
347:                                entry.getValue().setDbName(dbName);
348:                                log
349:                                        .debug("No db name set for relation; using default "
350:                                                + entry.getValue().getDbName());
351:                            }
352:                        }
353:                    }
354:                }
355:            }
356:
357:            /**
358:             * Determines whether the inspected entity class uses entity inheritance and of what type.
359:             * Also determines discriminator attributes for the single-table inheritance strategy.
360:             * @param toInspect		the class that is inspected
361:             */
362:            private void processInheritance(Class<T> toInspect) {
363:                // Find the root of the entity class hierarchy
364:                Class<? super  T> baseClass = toInspect;
365:                while (baseClass.getSuperclass().getAnnotation(Entity.class) != null) {
366:                    baseClass = baseClass.getSuperclass();
367:                }
368:                // If root is same as class to inspect, there is no inheritance. 
369:                if (!baseClass.equals(toInspect)) {
370:                    Inheritance inheritanceAnnotation = baseClass
371:                            .getAnnotation(Inheritance.class);
372:                    inheritanceStrategy = inheritanceAnnotation != null ? inheritanceAnnotation
373:                            .strategy()
374:                            : null;
375:                    if (inheritanceStrategy == null) {
376:                        log.debug("strategy is null -> taking default");
377:                        inheritanceStrategy = InheritanceType.SINGLE_TABLE;
378:                    } else {
379:                        log.debug("strategy is: " + inheritanceStrategy);
380:                    }
381:
382:                    if (inheritanceStrategy
383:                            .equals(InheritanceType.SINGLE_TABLE)) {
384:                        // Table is specified as annotation on root entity
385:                        Table tableAnnotation = baseClass
386:                                .getAnnotation(Table.class);
387:                        if (tableAnnotation != null) {
388:                            this .tableName = tableAnnotation.name();
389:                        } else {
390:                            this .tableName = generateDefautTableName(baseClass,
391:                                    baseClass.getAnnotation(Entity.class));
392:                        }
393:                        // Determine what discriminator to use
394:                        DiscriminatorColumn discriminatorColumn = baseClass
395:                                .getAnnotation(DiscriminatorColumn.class);
396:                        if (discriminatorColumn != null) {
397:                            this .discriminatorName = discriminatorColumn.name();
398:                            switch (discriminatorColumn.discriminatorType()) {
399:                            case INTEGER:
400:                                discriminatorType = Integer.class;
401:                                break;
402:                            case STRING:
403:                                discriminatorType = String.class;
404:                                break;
405:                            case CHAR:
406:                                discriminatorType = Character.class;
407:                                break;
408:                            }
409:                            //this.discriminatorProperty = new DiscriminatorProperty(toInspect, discriminatorName, type); 
410:                        } else {
411:                            // Use defaults:
412:                            this .discriminatorName = "DTYPE";
413:                            this .discriminatorType = String.class;
414:                        }
415:                        // Find discriminator value
416:                        DiscriminatorValue discriminatorValueAnnotation = toInspect
417:                                .getAnnotation(DiscriminatorValue.class);
418:                        if (discriminatorValueAnnotation != null) {
419:                            this .discriminatorValue = discriminatorValueAnnotation
420:                                    .value();
421:                        }
422:                    } else {
423:                        log.debug("Inheritance strategy " + inheritanceStrategy
424:                                + " not (yet) supported.");
425:                    }
426:                }
427:            }
428:
429:            /**
430:             * @return	true when entity uses single-table inheritance strategy
431:             */
432:            public boolean usesSingleTableInheritance() {
433:                return inheritanceStrategy != null
434:                        && inheritanceStrategy
435:                                .equals(InheritanceType.SINGLE_TABLE);
436:            }
437:
438:            /**
439:             * @return	name of discriminator (column), or null if not used.
440:             */
441:            public String getDiscriminatorName() {
442:                return discriminatorName;
443:            }
444:
445:            /**
446:             * @return	discriminator value used for the class that is inspected by this object,
447:             * or null if not used.
448:             */
449:            public String getDiscriminatorValue() {
450:                return discriminatorValue;
451:            }
452:
453:            /**
454:             * Returns discriminator type used for the class that is inspected by this object,
455:             * or null if not used.
456:             * @return		one of Integer.class, String.class or Character.class
457:             */
458:            public Class getDiscriminatorType() {
459:                return discriminatorType;
460:            }
461:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.