KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > ejbcore > ejb > wizard > cmp > CmpFromDbGenerator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.j2ee.ejbcore.ejb.wizard.cmp;
21
22 import java.util.Arrays JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.Collections JavaDoc;
25 import org.netbeans.api.project.Project;
26 import org.netbeans.modules.j2ee.dd.api.ejb.DDProvider;
27 import org.netbeans.modules.j2ee.dd.api.ejb.EjbJar;
28 import org.netbeans.modules.j2ee.ejbcore.EjbGenerationUtil;
29 import org.netbeans.modules.j2ee.persistence.entitygenerator.EntityClass;
30 import org.netbeans.modules.j2ee.persistence.entitygenerator.EntityMember;
31 import org.openide.filesystems.FileObject;
32 import java.io.IOException JavaDoc;
33 import java.text.MessageFormat JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.List JavaDoc;
37 import javax.lang.model.element.Modifier;
38 import org.netbeans.api.db.explorer.DatabaseConnection;
39 import org.netbeans.modules.j2ee.common.method.MethodModel;
40 import org.netbeans.modules.j2ee.common.source.GenerationUtils;
41 import org.netbeans.modules.j2ee.dd.api.ejb.CmpField;
42 import org.netbeans.modules.j2ee.dd.api.ejb.CmrField;
43 import org.netbeans.modules.j2ee.dd.api.ejb.EjbRelation;
44 import org.netbeans.modules.j2ee.dd.api.ejb.EjbRelationshipRole;
45 import org.netbeans.modules.j2ee.dd.api.ejb.EnterpriseBeans;
46 import org.netbeans.modules.j2ee.dd.api.ejb.Entity;
47 import org.netbeans.modules.j2ee.dd.api.ejb.RelationshipRoleSource;
48 import org.netbeans.modules.j2ee.dd.api.ejb.Relationships;
49 import org.netbeans.modules.j2ee.deployment.common.api.OriginalCMPMapping;
50 import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
51 import org.netbeans.modules.j2ee.ejbcore.action.CmFieldGenerator;
52 import org.netbeans.modules.j2ee.ejbcore.action.FinderMethodGenerator;
53 import org.netbeans.modules.j2ee.ejbcore.api.codegeneration.EntityGenerator;
54 import org.netbeans.modules.j2ee.ejbcore.api.methodcontroller.EntityMethodController;
55 import org.netbeans.modules.j2ee.ejbcore.naming.EJBNameOptions;
56 import org.netbeans.modules.j2ee.ejbcore.spi.ProjectPropertiesSupport;
57 import org.netbeans.modules.j2ee.persistence.entitygenerator.EntityRelation;
58 import org.netbeans.modules.j2ee.persistence.entitygenerator.RelationshipRole;
59 import org.netbeans.modules.j2ee.persistence.wizard.fromdb.RelatedCMPHelper;
60 import org.netbeans.modules.j2ee.persistence.wizard.fromdb.TableSource;
61 import org.openide.util.NbBundle;
62
63 /**
64  *
65  * @author Martin Adamek
66  */

67 public class CmpFromDbGenerator {
68     
69     private static final String JavaDoc FINDER_EXCEPTION_CLASS = "javax.ejb.FinderException"; //NOI18N
70
private static final List JavaDoc PRIMITIVE_CLASS_NAMES = Arrays.asList(
71             "boolean", "byte", "char", "short", "int", "long", "float", "double"); //NOI18N
72

73     private final Project project;
74     private final FileObject ddFileObject;
75     private final EjbJar dd;
76     
77     public CmpFromDbGenerator(Project project, FileObject ddFileObject) throws IOException JavaDoc {
78         this.project = project;
79         this.ddFileObject = ddFileObject;
80         this.dd = DDProvider.getDefault().getDDRoot(ddFileObject);
81     }
82     
83     public void generateBeans(RelatedCMPHelper helper, FileObject dbschemaFile, ProgressNotifier progressNotifier) throws IOException JavaDoc {
84         
85         disableSunCmpMappingsExclusion();
86         J2eeModuleProvider pwm = project.getLookup().lookup(J2eeModuleProvider.class);
87         pwm.getConfigSupport().ensureConfigurationReady();
88         
89         if (dd.getEnterpriseBeans()==null) {
90             EnterpriseBeans eBeans = dd.newEnterpriseBeans();
91             dd.setEnterpriseBeans(eBeans);
92         }
93         
94         int max = 2 * helper.getBeans().length + 4;
95         int entityClassIndex = 0;
96         progressNotifier.switchToDeterminate(max);
97         OriginalCMPMapping[] mappings = new OriginalCMPMapping[helper.getBeans().length];
98         
99         for (EntityClass entityClass : helper.getBeans()) {
100             progressNotifier.progress(NbBundle.getMessage(CmpGenerator.class, "TXT_GeneratingClasses", entityClass.getClassName()));
101             entityClassIndex++;
102             String JavaDoc pkClassName = null;
103             List JavaDoc<EntityMember> primaryKeys = new ArrayList JavaDoc<EntityMember>();
104             for (EntityMember entityMember : entityClass.getFields()) {
105                 if (entityMember.isPrimaryKey()) {
106                     pkClassName = entityMember.getMemberType();
107                     primaryKeys.add(entityMember);
108                 }
109             }
110             if (primaryKeys.size() > 1) {
111                 String JavaDoc pkFieldName = entityClass.getPkFieldName();
112                 pkClassName = Character.toUpperCase(pkFieldName.charAt(0)) + pkFieldName.substring(1);
113                 GenerationUtils.createClass(
114                         "Templates/J2EE/EJB21/CmpPrimaryKey.java",
115                         entityClass.getPackageFileObject(),
116                         pkClassName,
117                         null,
118                         Collections.singletonMap("seq", "")
119                         );
120             }
121             String JavaDoc wizardTargetName = entityClass.getClassName();
122             EntityGenerator generator = EntityGenerator.create(
123                     wizardTargetName,
124                     entityClass.getPackageFileObject(),
125                     false,
126                     true,
127                     true,
128                     pkClassName
129                     );
130             FileObject ejbClassFileObject = generator.generate();
131             
132             progressNotifier.progress(2*entityClassIndex+3);
133             EJBNameOptions ejbnames = new EJBNameOptions();
134             String JavaDoc ejbClassName = ejbnames.getEntityEjbClassPrefix() + wizardTargetName + ejbnames.getEntityEjbClassSuffix();
135             Entity e = findEntity(ejbClassFileObject, ejbClassName);
136             FinderMethodGenerator finderGenerator = FinderMethodGenerator.create(e, ejbClassFileObject, ddFileObject);
137             // if (helper.isGenerateFinderMethods()) { // is it possible to have CMP with finder method in impl class?
138
progressNotifier.progress(NbBundle.getMessage(CmpGenerator.class, "TXT_GeneratingFinderMethods", wizardTargetName));
139             addFinderMethods(finderGenerator, e, entityClass.getPackageFileObject(), entityClass, helper.isCmpFieldsInInterface());
140             // }
141

142             addCmpFields(e, entityClass);
143             addRelationshipFields(e, entityClass);
144             populateEntity(entityClass, e, wizardTargetName);
145             
146             DatabaseConnection dbconn = helper.getDatabaseConnection();
147             if(dbconn != null) {
148                 e.setDescription(dbconn.getName());
149             }
150             progressNotifier.progress(NbBundle.getMessage(CmpGenerator.class, "TXT_PersistingOriginalMapping", entityClass.getClassName()));
151             mappings[entityClassIndex] = new CMPMapping(e.getEjbName(), entityClass.getCMPMapping(), dbschemaFile);
152             progressNotifier.progress(2*entityClassIndex+4);
153         }
154         
155         progressNotifier.progress(NbBundle.getMessage(CmpGenerator.class, "TXT_GeneratingRelationships"));
156         EntityRelation[] relation = helper.getRelations();
157         if (dd.getSingleRelationships() == null && relation.length > 0) {
158             dd.setRelationships(dd.newRelationships());
159         }
160         Relationships rels = dd.getSingleRelationships();
161         for (int i = 0; i < relation.length; i++) {
162             EjbRelation ejbRel = rels.newEjbRelation();
163             populateRelation(ejbRel, relation[i]);
164             rels.addEjbRelation(ejbRel);
165         }
166         progressNotifier.progress(max - 1);
167         progressNotifier.progress(NbBundle.getMessage(CmpGenerator.class, "TXT_SavingDeploymentDescriptor"));
168         
169         //push mapping information
170
if (pwm != null) {
171             pwm.getConfigSupport().setCMPMappingInfo(mappings);
172         }
173         dd.write(ddFileObject);
174         if (pwm != null) {
175             for (EntityClass entityClass : helper.getBeans()) {
176                 if (helper.getTableSource().getType() == TableSource.Type.DATA_SOURCE) {
177                     pwm.getConfigSupport().ensureResourceDefinedForEjb(entityClass.getClassName(), "entity", helper.getTableSource().getName()); //NOI18N
178
}
179             }
180         }
181         progressNotifier.progress(max);
182     }
183     
184     private void addFinderMethods(FinderMethodGenerator generator, Entity e, FileObject pkg, EntityClass genData, boolean generateLocal) throws IOException JavaDoc {
185         FileObject ejbClassFO = pkg.getFileObject(EjbGenerationUtil.getBaseName(e.getEjbClass()), "java"); // NOI18N
186
assert ejbClassFO != null: "interface class "+ e.getLocalHome() + " not found in " + pkg;
187         
188         Iterator JavaDoc<EntityMember> it = genData.getFields().iterator();
189         while (it.hasNext()) {
190             EntityMember em = (EntityMember) it.next();
191             String JavaDoc type = em.getMemberType();
192             if (em.supportsFinder()) { // TODO consider not generating for primary key
193
String JavaDoc methodName = "findBy" + EntityMember.makeClassName(em.getMemberName()); // NOI18N
194
MethodModel.Variable parameter = MethodModel.Variable.create(em.getMemberType(), em.getMemberName());
195                 MethodModel methodModel = MethodModel.create(
196                         methodName,
197                         "java.util.Collection",
198                         null,
199                         Collections.singletonList(parameter),
200                         Collections.singletonList(FINDER_EXCEPTION_CLASS),
201                         Collections.<Modifier>emptySet()
202                         );
203                 String JavaDoc ejbql = MessageFormat.format(
204                         "SELECT OBJECT({0}) " +
205                         "FROM {1} AS {0} " + // abstract schema name
206
"WHERE {0}.{2} = ?1", // cmp field
207
new Object JavaDoc[] {
208                     Character.toLowerCase(e.getAbstractSchemaName().charAt(0)) + "",
209                     e.getAbstractSchemaName(),
210                     em.getMemberName()
211                 }
212                 );
213                 generator.generate(methodModel, generateLocal, false, false, ejbql);
214             }
215         }
216         
217     }
218     
219 // /**
220
// * Determine if <code>className</code> is of a primitive type or not.
221
// * @return true if <code>className</code> is of a primitive type
222
// */
223
// private static boolean isPrimitive(String className) {
224
// return PRIMITIVE_CLASS_NAMES.contains(className);
225
// }
226

227     private void populateEntity(EntityClass bean, Entity e, String JavaDoc wizardTargetName) {
228         if (bean.isUsePkField()) {
229             e.setPrimkeyField(bean.getPkFieldName());
230         }
231         e.setAbstractSchemaName(wizardTargetName);
232         
233         Iterator JavaDoc it = bean.getFields().iterator();
234         while (it.hasNext()) {
235             EntityMember m = (EntityMember) it.next();
236             CmpField f = e.newCmpField();
237             f.setFieldName(m.getMemberName());
238             e.addCmpField(f);
239         }
240     }
241     
242     private void populateRelation(EjbRelation ejbR, EntityRelation r) {
243         RelationshipRole roleA = r.getRoleA();
244         RelationshipRole roleB = r.getRoleB();
245         
246         EjbRelationshipRole ejbRoleA = ejbR.newEjbRelationshipRole();
247         EjbRelationshipRole ejbRoleB = ejbR.newEjbRelationshipRole();
248         
249         populateRole(ejbRoleA, roleA);
250         populateRole(ejbRoleB, roleB);
251         
252         ejbR.setEjbRelationName(r.getRelationName());
253         ejbR.setEjbRelationshipRole(ejbRoleA);
254         ejbR.setEjbRelationshipRole2(ejbRoleB);
255     }
256     
257     private static void populateRole(EjbRelationshipRole ejbR, RelationshipRole role) {
258         ejbR.setCascadeDelete(role.isCascade());
259         RelationshipRoleSource source = ejbR.newRelationshipRoleSource();
260         source.setEjbName(role.getEntityName());
261         ejbR.setRelationshipRoleSource(source);
262         CmrField f = ejbR.newCmrField();
263         f.setCmrFieldName(role.getFieldName());
264         if (role.isMany()) {
265             ejbR.setMultiplicity(ejbR.MULTIPLICITY_MANY);
266         } else {
267             ejbR.setMultiplicity(ejbR.MULTIPLICITY_ONE);
268         }
269         if (role.isToMany()) {
270             f.setCmrFieldType(java.util.Collection JavaDoc.class.getName());
271         }
272         ejbR.setCmrField(f);
273         ejbR.setEjbRelationshipRoleName(role.getEntityName());
274     }
275     
276     private String JavaDoc getCmrFieldType(RelationshipRole role, String JavaDoc pkg) {
277         if (role.isToMany()) {
278             return java.util.Collection JavaDoc.class.getName();
279         } else {
280             RelationshipRole rA = role.getParent().getRoleA();
281             RelationshipRole rB = role.getParent().getRoleB();
282             RelationshipRole otherRole = role.equals(rA) ? rB : rA;
283             EJBNameOptions ejbNames = new EJBNameOptions();
284             String JavaDoc ejbClassName = ejbNames.getEntityEjbClassPrefix() + otherRole.getEntityName() + ejbNames.getEntityEjbClassSuffix();
285             Entity entity = (Entity) dd.getEnterpriseBeans().findBeanByName(EnterpriseBeans.ENTITY, Entity.EJB_CLASS, ejbClassName);
286             return entity.getLocal();
287         }
288     }
289     
290     /**
291      * Temporary fix for #53475. By default the sun-cmp-mappings.xml file is
292      * excluded from the JAR. It is again included when the user goes through this
293      * wizard.
294      */

295     private void disableSunCmpMappingsExclusion() {
296         if (org.netbeans.modules.j2ee.api.ejbjar.EjbJar.getEjbJars(project).length == 0) {
297             return;
298         }
299         ProjectPropertiesSupport ps = project.getLookup().lookup(ProjectPropertiesSupport.class);
300         if (ps != null) {
301             ps.disableSunCmpMappingExclusion();
302         }
303     }
304     
305     private void addCmpFields(Entity entity, EntityClass entityClass) throws IOException JavaDoc {
306         EJBNameOptions ejbNames = new EJBNameOptions();
307         String JavaDoc className = ejbNames.getEntityEjbClassPrefix() + entityClass.getClassName() + ejbNames.getEntityEjbClassSuffix();
308         FileObject ejbClassFO = entityClass.getPackageFileObject().getFileObject(EjbGenerationUtil.getBaseName(className), "java"); // NOI18N
309
EntityMethodController emc = (EntityMethodController) EntityMethodController.createFromClass(ejbClassFO, className);
310         for (EntityMember m : entityClass.getFields()) {
311             emc.addField(
312                     MethodModel.Variable.create(m.getMemberType(), m.getMemberName()),
313                     ddFileObject,
314                     true,
315                     true,
316                     false,
317                     false,
318                     null
319                     );
320         }
321     }
322     
323     /**
324      * Doesn't write entry to deployment descriptor
325      */

326     private void addRelationshipFields(Entity entity, EntityClass entityClass) throws IOException JavaDoc {
327         FileObject ejbClassFO = entityClass.getPackageFileObject().getFileObject(EjbGenerationUtil.getBaseName(entity.getEjbClass()), "java"); // NOI18N
328
CmFieldGenerator generator = CmFieldGenerator.create(entity, ejbClassFO, ddFileObject);
329         for (RelationshipRole role : entityClass.getRoles()) {
330             String JavaDoc rv = getCmrFieldType(role, entityClass.getPackage());
331             MethodModel.Variable field = MethodModel.Variable.create(rv, role.getFieldName());
332             generator.addFieldToClass(field, true, true, false, false);
333         }
334     }
335     
336     private static Entity findEntity(FileObject fileObject, String JavaDoc className) throws IOException JavaDoc {
337         org.netbeans.modules.j2ee.api.ejbjar.EjbJar ejbModule = org.netbeans.modules.j2ee.api.ejbjar.EjbJar.getEjbJar(fileObject);
338         if (ejbModule != null) {
339             EjbJar ejbJar = DDProvider.getDefault().getMergedDDRoot(ejbModule.getMetadataUnit());
340             if (ejbJar != null) {
341                 EnterpriseBeans enterpriseBeans = ejbJar.getEnterpriseBeans();
342                 if (enterpriseBeans != null) {
343                     return (Entity) enterpriseBeans.findBeanByName(EnterpriseBeans.ENTITY, Entity.EJB_CLASS, className);
344                 }
345             }
346         }
347         return null;
348     }
349     
350     public static interface ProgressNotifier {
351         
352         void switchToDeterminate(int workunits);
353         
354         void progress(int workunit);
355         
356         void progress(String JavaDoc message);
357         
358     }
359     
360 }
361
Popular Tags