KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > jpa > bridge > DataMapConverter


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.jpa.bridge;
21
22 import java.beans.PropertyDescriptor JavaDoc;
23 import java.lang.reflect.Field JavaDoc;
24
25 import org.apache.cayenne.jpa.JpaProviderException;
26 import org.apache.cayenne.jpa.conf.EntityMapLoaderContext;
27 import org.apache.cayenne.jpa.map.AccessType;
28 import org.apache.cayenne.jpa.map.JpaAttribute;
29 import org.apache.cayenne.jpa.map.JpaAttributes;
30 import org.apache.cayenne.jpa.map.JpaBasic;
31 import org.apache.cayenne.jpa.map.JpaColumn;
32 import org.apache.cayenne.jpa.map.JpaEntity;
33 import org.apache.cayenne.jpa.map.JpaEntityListener;
34 import org.apache.cayenne.jpa.map.JpaEntityListeners;
35 import org.apache.cayenne.jpa.map.JpaEntityMap;
36 import org.apache.cayenne.jpa.map.JpaId;
37 import org.apache.cayenne.jpa.map.JpaJoinColumn;
38 import org.apache.cayenne.jpa.map.JpaManagedClass;
39 import org.apache.cayenne.jpa.map.JpaManyToMany;
40 import org.apache.cayenne.jpa.map.JpaManyToOne;
41 import org.apache.cayenne.jpa.map.JpaNamedQuery;
42 import org.apache.cayenne.jpa.map.JpaOneToMany;
43 import org.apache.cayenne.jpa.map.JpaOneToOne;
44 import org.apache.cayenne.jpa.map.JpaPersistenceUnitDefaults;
45 import org.apache.cayenne.jpa.map.JpaPersistenceUnitMetadata;
46 import org.apache.cayenne.jpa.map.JpaQueryHint;
47 import org.apache.cayenne.jpa.map.JpaRelationship;
48 import org.apache.cayenne.jpa.map.JpaTable;
49 import org.apache.cayenne.jpa.map.JpaVersion;
50 import org.apache.cayenne.map.DataMap;
51 import org.apache.cayenne.map.DbAttribute;
52 import org.apache.cayenne.map.DbEntity;
53 import org.apache.cayenne.map.DbJoin;
54 import org.apache.cayenne.map.DbRelationship;
55 import org.apache.cayenne.map.EntityListener;
56 import org.apache.cayenne.map.ObjAttribute;
57 import org.apache.cayenne.map.ObjEntity;
58 import org.apache.cayenne.map.ObjRelationship;
59 import org.apache.cayenne.project.ProjectPath;
60 import org.apache.cayenne.util.BaseTreeVisitor;
61 import org.apache.cayenne.util.HierarchicalTreeVisitor;
62 import org.apache.cayenne.util.TraversalUtil;
63 import org.apache.cayenne.util.Util;
64 import org.apache.cayenne.validation.SimpleValidationFailure;
65
66 /**
67  * A converter between {@link org.apache.cayenne.jpa.map.JpaEntityMap} and Cayenne
68  * {@link org.apache.cayenne.map.DataMap}.
69  *
70  * @author Andrus Adamchik
71  */

72 public class DataMapConverter {
73
74     protected EntityMapLoaderContext context;
75
76     protected ProjectPath targetPath;
77     protected HierarchicalTreeVisitor visitor;
78
79     public synchronized DataMap toDataMap(String JavaDoc name, EntityMapLoaderContext context) {
80         this.context = context;
81
82         // reset
83
DataMap dataMap = new DataMap(name);
84         dataMap.setDefaultPackage(context.getEntityMap().getPackageName());
85         dataMap.setDefaultSchema(context.getEntityMap().getSchema());
86
87         this.targetPath = new ProjectPath(dataMap);
88
89         if (visitor == null) {
90             visitor = createVisitor();
91         }
92
93         TraversalUtil.traverse(context.getEntityMap(), visitor);
94         return dataMap;
95     }
96
97     protected void recordConflict(ProjectPath path, String JavaDoc message) {
98         context.recordConflict(new SimpleValidationFailure(path.getObject(), message));
99     }
100
101     /**
102      * Creates a stateless instance of the JpaEntityMap traversal visitor. This method is
103      * lazily invoked and cached by this object.
104      */

105     protected HierarchicalTreeVisitor createVisitor() {
106         BaseTreeVisitor listenersVisitor = new BaseTreeVisitor();
107         listenersVisitor.addChildVisitor(
108                 JpaEntityListener.class,
109                 new JpaDefaultEntityListenerVisitor());
110
111         BaseTreeVisitor defaultsVisitor = new BaseTreeVisitor();
112         defaultsVisitor.addChildVisitor(JpaEntityListeners.class, listenersVisitor);
113         BaseTreeVisitor metadataVisitor = new BaseTreeVisitor();
114         metadataVisitor
115                 .addChildVisitor(JpaPersistenceUnitDefaults.class, defaultsVisitor);
116
117         BaseTreeVisitor visitor = new BaseTreeVisitor();
118         visitor.addChildVisitor(JpaEntity.class, new JpaEntityVisitor());
119         visitor.addChildVisitor(JpaNamedQuery.class, new JpaNamedQueryVisitor());
120         visitor.addChildVisitor(JpaPersistenceUnitMetadata.class, metadataVisitor);
121         return visitor;
122     }
123
124     private EntityListener makeEntityListener(JpaEntityListener jpaListener) {
125         EntityListener listener = new EntityListener(jpaListener.getClassName());
126
127         if (jpaListener.getPostLoad() != null) {
128             listener.getCallbackMap().getPostLoad().addCallbackMethod(
129                     jpaListener.getPostLoad().getMethodName());
130         }
131
132         if (jpaListener.getPostPersist() != null) {
133             listener.getCallbackMap().getPostPersist().addCallbackMethod(
134                     jpaListener.getPostPersist().getMethodName());
135         }
136
137         if (jpaListener.getPostRemove() != null) {
138             listener.getCallbackMap().getPostRemove().addCallbackMethod(
139                     jpaListener.getPostRemove().getMethodName());
140         }
141
142         if (jpaListener.getPostUpdate() != null) {
143             listener.getCallbackMap().getPostUpdate().addCallbackMethod(
144                     jpaListener.getPostUpdate().getMethodName());
145         }
146
147         if (jpaListener.getPrePersist() != null) {
148             listener.getCallbackMap().getPrePersist().addCallbackMethod(
149                     jpaListener.getPrePersist().getMethodName());
150         }
151
152         if (jpaListener.getPreRemove() != null) {
153             listener.getCallbackMap().getPreRemove().addCallbackMethod(
154                     jpaListener.getPreRemove().getMethodName());
155         }
156
157         if (jpaListener.getPreUpdate() != null) {
158             listener.getCallbackMap().getPreUpdate().addCallbackMethod(
159                     jpaListener.getPreUpdate().getMethodName());
160         }
161         return listener;
162     }
163
164     class JpaDefaultEntityListenerVisitor extends BaseTreeVisitor {
165
166         @Override JavaDoc
167         public boolean onStartNode(ProjectPath path) {
168             JpaEntityListener jpaListener = (JpaEntityListener) path.getObject();
169
170             DataMap map = (DataMap) targetPath.firstInstanceOf(DataMap.class);
171             EntityListener listener = map.getEntityListener(jpaListener.getClassName());
172             if (listener == null) {
173                 listener = makeEntityListener(jpaListener);
174                 map.addEntityListener(listener);
175             }
176
177             map.addDefaultEntityListener(listener);
178             return false;
179         }
180     }
181
182     class JpaEntityListenerVisitor extends BaseTreeVisitor {
183
184         @Override JavaDoc
185         public boolean onStartNode(ProjectPath path) {
186             JpaEntityListener jpaListener = (JpaEntityListener) path.getObject();
187
188             DataMap map = (DataMap) targetPath.firstInstanceOf(DataMap.class);
189             EntityListener listener = map.getEntityListener(jpaListener.getClassName());
190             if (listener == null) {
191                 listener = makeEntityListener(jpaListener);
192                 map.addEntityListener(listener);
193             }
194
195             ObjEntity entity = (ObjEntity) targetPath.firstInstanceOf(ObjEntity.class);
196             entity.addEntityListener(listener);
197
198             return false;
199         }
200     }
201
202     class JpaBasicVisitor extends NestedVisitor {
203
204         @Override JavaDoc
205         Object JavaDoc createObject(ProjectPath path) {
206
207             JpaBasic jpaBasic = (JpaBasic) path.getObject();
208
209             ObjEntity parentCayenneEntity = (ObjEntity) targetPath.getObject();
210
211             ObjAttribute cayenneAttribute = new ObjAttribute(jpaBasic.getName());
212             cayenneAttribute
213                     .setType(getAttributeType(path, jpaBasic.getName()).getName());
214             cayenneAttribute.setDbAttributeName(jpaBasic.getColumn().getName());
215
216             parentCayenneEntity.addAttribute(cayenneAttribute);
217             return cayenneAttribute;
218         }
219
220         Class JavaDoc getAttributeType(ProjectPath path, String JavaDoc name) {
221             AccessType access = null;
222
223             JpaManagedClass entity = (JpaManagedClass) path
224                     .firstInstanceOf(JpaManagedClass.class);
225             access = entity.getAccess();
226
227             if (access == null) {
228                 JpaEntityMap map = (JpaEntityMap) path
229                         .firstInstanceOf(JpaEntityMap.class);
230                 access = map.getAccess();
231             }
232
233             Class JavaDoc objectClass = ((ObjEntity) targetPath.firstInstanceOf(ObjEntity.class))
234                     .getJavaClass();
235
236             try {
237                 if (access == AccessType.FIELD) {
238                     return lookupFieldInHierarchy(objectClass, name).getType();
239                 }
240                 else {
241                     return new PropertyDescriptor JavaDoc(name, objectClass).getPropertyType();
242                 }
243             }
244             catch (Exception JavaDoc e) {
245                 throw new JpaProviderException("Error resolving attribute '"
246                         + name
247                         + "', access type:"
248                         + access
249                         + ", class: "
250                         + objectClass.getName(), e);
251             }
252         }
253
254         Field JavaDoc lookupFieldInHierarchy(Class JavaDoc beanClass, String JavaDoc fieldName)
255                 throws SecurityException JavaDoc, NoSuchFieldException JavaDoc {
256
257             try {
258                 return beanClass.getDeclaredField(fieldName);
259             }
260             catch (NoSuchFieldException JavaDoc e) {
261
262                 Class JavaDoc superClass = beanClass.getSuperclass();
263                 if (superClass == null
264                         || superClass.getName().equals(Object JavaDoc.class.getName())) {
265                     throw e;
266                 }
267
268                 return lookupFieldInHierarchy(superClass, fieldName);
269             }
270         }
271     }
272
273     class JpaVersionVisitor extends JpaBasicVisitor {
274
275         @Override JavaDoc
276         Object JavaDoc createObject(ProjectPath path) {
277
278             JpaVersion version = (JpaVersion) path.getObject();
279
280             ObjEntity parentCayenneEntity = (ObjEntity) targetPath.getObject();
281
282             ObjAttribute cayenneAttribute = new ObjAttribute(version.getName());
283             cayenneAttribute.setType(getAttributeType(path, version.getName()).getName());
284             cayenneAttribute.setDbAttributeName(version.getColumn().getName());
285
286             parentCayenneEntity.addAttribute(cayenneAttribute);
287             return cayenneAttribute;
288         }
289     }
290
291     class JpaColumnVisitor extends BaseTreeVisitor {
292
293         @Override JavaDoc
294         public boolean onStartNode(ProjectPath path) {
295             JpaColumn jpaColumn = (JpaColumn) path.getObject();
296             JpaAttribute attribute = (JpaAttribute) path.getObjectParent();
297
298             DbAttribute dbAttribute = new DbAttribute(jpaColumn.getName());
299
300             if (attribute instanceof JpaBasic) {
301                 JpaBasic basic = (JpaBasic) attribute;
302                 dbAttribute.setType(basic.getDefaultJdbcType());
303             }
304             else if (attribute instanceof JpaVersion) {
305                 JpaVersion version = (JpaVersion) attribute;
306                 dbAttribute.setType(version.getDefaultJdbcType());
307             }
308
309             dbAttribute.setMandatory(!jpaColumn.isNullable());
310             dbAttribute.setMaxLength(jpaColumn.getLength());
311
312             // DbAttribute "no scale" means -1, not 0 like in JPA.
313
if (jpaColumn.getScale() > 0) {
314                 dbAttribute.setScale(jpaColumn.getScale());
315             }
316
317             // DbAttribute "no precision" means -1, not 0 like in JPA.
318
if (jpaColumn.getPrecision() > 0) {
319                 dbAttribute.setAttributePrecision(jpaColumn.getPrecision());
320             }
321
322             if (jpaColumn.getTable() == null) {
323                 throw new JpaProviderException("No default table defined for JpaColumn "
324                         + jpaColumn.getName());
325             }
326
327             DbEntity entity = ((DataMap) targetPath.firstInstanceOf(DataMap.class))
328                     .getDbEntity(jpaColumn.getTable());
329
330             if (entity == null) {
331                 throw new JpaProviderException("No DbEntity defined for table "
332                         + jpaColumn.getTable());
333             }
334
335             entity.addAttribute(dbAttribute);
336
337             return false;
338         }
339     }
340
341     class JpaIdVisitor extends JpaBasicVisitor {
342
343         @Override JavaDoc
344         Object JavaDoc createObject(ProjectPath path) {
345
346             JpaId id = (JpaId) path.getObject();
347
348             ObjEntity parentCayenneEntity = (ObjEntity) targetPath.getObject();
349
350             ObjAttribute cayenneAttribute = new ObjAttribute(id.getName());
351             cayenneAttribute.setType(getAttributeType(path, id.getName()).getName());
352             cayenneAttribute.setDbAttributeName(id.getColumn().getName());
353
354             parentCayenneEntity.addAttribute(cayenneAttribute);
355             return cayenneAttribute;
356         }
357     }
358
359     class JpaIdColumnVisitor extends BaseTreeVisitor {
360
361         @Override JavaDoc
362         public boolean onStartNode(ProjectPath path) {
363             JpaColumn jpaColumn = (JpaColumn) path.getObject();
364
365             DbAttribute dbAttribute = new DbAttribute(jpaColumn.getName());
366
367             JpaId jpaId = (JpaId) path.firstInstanceOf(JpaId.class);
368
369             dbAttribute.setType(jpaId.getDefaultJdbcType());
370
371             dbAttribute.setMaxLength(jpaColumn.getLength());
372             dbAttribute.setMandatory(true);
373             dbAttribute.setPrimaryKey(true);
374
375             if (jpaColumn.getScale() > 0) {
376                 dbAttribute.setScale(jpaColumn.getScale());
377             }
378
379             if (jpaColumn.getPrecision() > 0) {
380                 dbAttribute.setAttributePrecision(jpaColumn.getPrecision());
381             }
382
383             if (jpaColumn.getTable() == null) {
384                 recordConflict(path, "No table defined for JpaColumn '"
385                         + jpaColumn.getName()
386                         + "'");
387                 return false;
388             }
389
390             DbEntity entity = ((DataMap) targetPath.firstInstanceOf(DataMap.class))
391                     .getDbEntity(jpaColumn.getTable());
392
393             if (entity == null) {
394                 recordConflict(path, "Invalid table definition for JpaColumn: "
395                         + jpaColumn.getTable()
396                         + "'");
397                 return false;
398             }
399
400             entity.addAttribute(dbAttribute);
401             return false;
402         }
403     }
404
405     class JpaJoinColumnVisitor extends BaseTreeVisitor {
406
407         @Override JavaDoc
408         public boolean onStartNode(ProjectPath path) {
409
410             JpaJoinColumn jpaJoin = (JpaJoinColumn) path.getObject();
411             JpaRelationship jpaRelationship = (JpaRelationship) path.getObjectParent();
412             JpaEntity targetEntity = context.getEntityMap().entityForClass(
413                     jpaRelationship.getTargetEntityName());
414             JpaId jpaTargetId = targetEntity.getAttributes().getId(
415                     jpaJoin.getReferencedColumnName());
416
417             ObjRelationship objRelationship = (ObjRelationship) targetPath.getObject();
418             DataMap dataMap = objRelationship.getSourceEntity().getDataMap();
419
420             // add FK
421
DbAttribute src = new DbAttribute(jpaJoin.getName());
422
423             // TODO: andrus, 5/2/2006 - infer this from Jpa relationship
424
src.setMandatory(false);
425
426             src.setMaxLength(jpaTargetId.getColumn().getLength());
427             src.setType(jpaTargetId.getDefaultJdbcType());
428
429             DbEntity srcEntity = dataMap.getDbEntity(jpaJoin.getTable());
430             srcEntity.addAttribute(src);
431
432             // add join
433
DbRelationship dbRelationship = (DbRelationship) objRelationship
434                     .getDbRelationships()
435                     .get(0);
436
437             DbRelationship reverseRelationship = dbRelationship.getReverseRelationship();
438             if (reverseRelationship == null) {
439                 reverseRelationship = dbRelationship.createReverseRelationship();
440             }
441
442             DbJoin join = new DbJoin(dbRelationship, src.getName(), jpaTargetId
443                     .getColumn()
444                     .getName());
445             DbJoin reverseJoin = join.createReverseJoin();
446             reverseJoin.setRelationship(reverseRelationship);
447
448             dbRelationship.addJoin(join);
449             reverseRelationship.addJoin(reverseJoin);
450
451             return false;
452         }
453     }
454
455     class JpaEntityVisitor extends NestedVisitor {
456
457         JpaEntityVisitor() {
458
459             BaseTreeVisitor listenersVisitor = new BaseTreeVisitor();
460             listenersVisitor.addChildVisitor(
461                     JpaEntityListener.class,
462                     new JpaEntityListenerVisitor());
463
464             BaseTreeVisitor attributeVisitor = new BaseTreeVisitor();
465             attributeVisitor.addChildVisitor(
466                     JpaManyToOne.class,
467                     new JpaRelationshipVisitor());
468             attributeVisitor.addChildVisitor(
469                     JpaOneToOne.class,
470                     new JpaRelationshipVisitor());
471             attributeVisitor.addChildVisitor(
472                     JpaOneToMany.class,
473                     new JpaRelationshipVisitor());
474             attributeVisitor.addChildVisitor(
475                     JpaManyToMany.class,
476                     new JpaRelationshipVisitor());
477
478             JpaBasicVisitor basicVisitor = new JpaBasicVisitor();
479             basicVisitor.addChildVisitor(JpaColumn.class, new JpaColumnVisitor());
480             attributeVisitor.addChildVisitor(JpaBasic.class, basicVisitor);
481
482             JpaVersionVisitor versionVisitor = new JpaVersionVisitor();
483             versionVisitor.addChildVisitor(JpaColumn.class, new JpaColumnVisitor());
484             attributeVisitor.addChildVisitor(JpaVersion.class, versionVisitor);
485
486             JpaIdVisitor idVisitor = new JpaIdVisitor();
487             idVisitor.addChildVisitor(JpaColumn.class, new JpaIdColumnVisitor());
488             attributeVisitor.addChildVisitor(JpaId.class, idVisitor);
489
490             // TODO: andrus 8/6/2006 - handle Embedded, EmbeddedId, AttributeOverride
491

492             addChildVisitor(JpaAttributes.class, attributeVisitor);
493             addChildVisitor(JpaTable.class, new JpaTableVisitor());
494             addChildVisitor(JpaNamedQuery.class, new JpaNamedQueryVisitor());
495             addChildVisitor(JpaEntityListeners.class, listenersVisitor);
496         }
497
498         @Override JavaDoc
499         Object JavaDoc createObject(ProjectPath path) {
500             JpaEntity jpaEntity = (JpaEntity) path.getObject();
501             ObjEntity cayenneEntity = new ObjEntity(jpaEntity.getName());
502             cayenneEntity.setClassName(jpaEntity.getClassName());
503             initCallbacks(jpaEntity, cayenneEntity);
504
505             ((DataMap) targetPath.getObject()).addObjEntity(cayenneEntity);
506
507             return cayenneEntity;
508         }
509
510         private void initCallbacks(JpaEntity jpaEntity, ObjEntity cayenneEntity) {
511             if (jpaEntity.getPostLoad() != null) {
512                 cayenneEntity.getCallbackMap().getPostLoad().addCallbackMethod(
513                         jpaEntity.getPostLoad().getMethodName());
514             }
515
516             if (jpaEntity.getPostPersist() != null) {
517                 cayenneEntity.getCallbackMap().getPostPersist().addCallbackMethod(
518                         jpaEntity.getPostPersist().getMethodName());
519             }
520
521             if (jpaEntity.getPostRemove() != null) {
522                 cayenneEntity.getCallbackMap().getPostRemove().addCallbackMethod(
523                         jpaEntity.getPostRemove().getMethodName());
524             }
525
526             if (jpaEntity.getPostUpdate() != null) {
527                 cayenneEntity.getCallbackMap().getPostUpdate().addCallbackMethod(
528                         jpaEntity.getPostUpdate().getMethodName());
529             }
530
531             if (jpaEntity.getPrePersist() != null) {
532                 cayenneEntity.getCallbackMap().getPrePersist().addCallbackMethod(
533                         jpaEntity.getPrePersist().getMethodName());
534             }
535
536             if (jpaEntity.getPreRemove() != null) {
537                 cayenneEntity.getCallbackMap().getPreRemove().addCallbackMethod(
538                         jpaEntity.getPreRemove().getMethodName());
539             }
540
541             if (jpaEntity.getPreUpdate() != null) {
542                 cayenneEntity.getCallbackMap().getPreUpdate().addCallbackMethod(
543                         jpaEntity.getPreUpdate().getMethodName());
544             }
545         }
546     }
547
548     class JpaRelationshipVisitor extends NestedVisitor {
549
550         JpaRelationshipVisitor() {
551             addChildVisitor(JpaJoinColumn.class, new JpaJoinColumnVisitor());
552         }
553
554         @Override JavaDoc
555         Object JavaDoc createObject(ProjectPath path) {
556
557             JpaRelationship relationship = (JpaRelationship) path.getObject();
558
559             ObjEntity cayenneSrcEntity = (ObjEntity) targetPath.getObject();
560             ObjRelationship cayenneRelationship = new ObjRelationship(relationship
561                     .getName());
562
563             cayenneSrcEntity.addRelationship(cayenneRelationship);
564
565             JpaEntity jpaTargetEntity = ((JpaEntityMap) path.getRoot())
566                     .entityForClass(relationship.getTargetEntityName());
567
568             if (jpaTargetEntity == null) {
569                 recordConflict(path, "Unknown target entity '"
570                         + relationship.getTargetEntityName());
571                 return null;
572             }
573
574             cayenneRelationship.setTargetEntityName(jpaTargetEntity.getName());
575
576             // TODO: db relationship should probably be created when the first join is
577
// created...
578
DbEntity cayenneSrcDbEntity = cayenneSrcEntity.getDbEntity();
579
580             DbEntity cayenneTargetDbEntity = cayenneSrcEntity.getDataMap().getDbEntity(
581                     jpaTargetEntity.getTable().getName());
582             if (cayenneTargetDbEntity == null) {
583                 cayenneTargetDbEntity = new DbEntity(jpaTargetEntity.getTable().getName());
584                 cayenneSrcEntity.getDataMap().addDbEntity(cayenneTargetDbEntity);
585             }
586
587             DbRelationship dbRelationship = new DbRelationship(cayenneRelationship
588                     .getName());
589             dbRelationship.setTargetEntity(cayenneTargetDbEntity);
590             dbRelationship.setToMany(relationship.isToMany());
591
592             cayenneSrcDbEntity.addRelationship(dbRelationship);
593             cayenneRelationship.addDbRelationship(dbRelationship);
594
595             return cayenneRelationship;
596         }
597     }
598
599     class JpaNamedQueryVisitor extends NestedVisitor {
600
601         @Override JavaDoc
602         Object JavaDoc createObject(ProjectPath path) {
603             JpaNamedQuery jpaQuery = (JpaNamedQuery) path.getObject();
604             JpaIndirectQuery cayenneQuery;
605
606             JpaQueryHint hint = jpaQuery.getHint(QueryHints.QUERY_TYPE_HINT);
607             if (hint != null && !Util.isEmptyString(hint.getValue())) {
608                 try {
609
610                     // query class is not enhanced, so use normal class loader
611
Class JavaDoc cayenneQueryClass = Class.forName(hint.getValue(), true, Thread
612                             .currentThread()
613                             .getContextClassLoader());
614
615                     if (!JpaIndirectQuery.class.isAssignableFrom(cayenneQueryClass)) {
616                         recordConflict(path, "Unknown type for Cayenne query '"
617                                 + jpaQuery.getName()
618                                 + "': "
619                                 + cayenneQueryClass.getName());
620                         return null;
621                     }
622
623                     cayenneQuery = (JpaIndirectQuery) cayenneQueryClass.newInstance();
624                 }
625                 catch (Exception JavaDoc e) {
626                     recordConflict(path, "Problem while creating Cayenne query '"
627                             + jpaQuery.getName()
628                             + "', exception"
629                             + e.getMessage());
630                     return null;
631                 }
632             }
633             else {
634                 // by default use EJBQL query...
635
cayenneQuery = new JpaEjbQLQuery();
636             }
637
638             cayenneQuery.setName(jpaQuery.getName());
639             cayenneQuery.setJpaQuery(jpaQuery);
640
641             DataMap parentMap = (DataMap) targetPath.firstInstanceOf(DataMap.class);
642
643             ObjEntity parentEntity = (ObjEntity) targetPath
644                     .firstInstanceOf(ObjEntity.class);
645             if (parentEntity != null) {
646                 cayenneQuery.setParentEntity(parentEntity);
647             }
648             else {
649                 cayenneQuery.setParentMap(parentMap);
650             }
651
652             parentMap.addQuery(cayenneQuery);
653
654             return cayenneQuery;
655         }
656     }
657
658     class JpaTableVisitor extends NestedVisitor {
659
660         @Override JavaDoc
661         Object JavaDoc createObject(ProjectPath path) {
662
663             JpaTable jpaTable = (JpaTable) path.getObject();
664             ObjEntity parentCayenneEntity = (ObjEntity) targetPath.getObject();
665
666             DbEntity cayenneEntity = parentCayenneEntity.getDataMap().getDbEntity(
667                     jpaTable.getName());
668             if (cayenneEntity == null) {
669                 cayenneEntity = new DbEntity(jpaTable.getName());
670                 parentCayenneEntity.getDataMap().addDbEntity(cayenneEntity);
671             }
672
673             cayenneEntity.setCatalog(jpaTable.getCatalog());
674             cayenneEntity.setSchema(jpaTable.getSchema());
675
676             parentCayenneEntity.setDbEntity(cayenneEntity);
677             return cayenneEntity;
678         }
679     }
680
681     /**
682      * A superclass of visitors that need to push/pop processed object from the stack.
683      */

684     abstract class NestedVisitor extends BaseTreeVisitor {
685
686         abstract Object JavaDoc createObject(ProjectPath path);
687
688         @Override JavaDoc
689         public boolean onStartNode(ProjectPath path) {
690             Object JavaDoc object = createObject(path);
691
692             if (object != null) {
693                 targetPath = targetPath.appendToPath(object);
694                 return true;
695             }
696             else {
697                 return false;
698             }
699         }
700
701         @Override JavaDoc
702         public void onFinishNode(ProjectPath path) {
703             targetPath = targetPath.subpathWithSize(targetPath.getPath().length - 1);
704         }
705     }
706 }
707
Popular Tags