1 19 20 package org.netbeans.modules.j2ee.ejbcore.ejb.wizard.cmp; 21 22 import java.util.Arrays ; 23 import java.util.Collections ; 24 import java.util.Collections ; 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 ; 33 import java.text.MessageFormat ; 34 import java.util.ArrayList ; 35 import java.util.Iterator ; 36 import java.util.List ; 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 67 public class CmpFromDbGenerator { 68 69 private static final String FINDER_EXCEPTION_CLASS = "javax.ejb.FinderException"; private static final List PRIMITIVE_CLASS_NAMES = Arrays.asList( 71 "boolean", "byte", "char", "short", "int", "long", "float", "double"); 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 { 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 { 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 pkClassName = null; 103 List <EntityMember> primaryKeys = new ArrayList <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 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 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 ejbClassName = ejbnames.getEntityEjbClassPrefix() + wizardTargetName + ejbnames.getEntityEjbClassSuffix(); 135 Entity e = findEntity(ejbClassFileObject, ejbClassName); 136 FinderMethodGenerator finderGenerator = FinderMethodGenerator.create(e, ejbClassFileObject, ddFileObject); 137 progressNotifier.progress(NbBundle.getMessage(CmpGenerator.class, "TXT_GeneratingFinderMethods", wizardTargetName)); 139 addFinderMethods(finderGenerator, e, entityClass.getPackageFileObject(), entityClass, helper.isCmpFieldsInInterface()); 140 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 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()); } 179 } 180 } 181 progressNotifier.progress(max); 182 } 183 184 private void addFinderMethods(FinderMethodGenerator generator, Entity e, FileObject pkg, EntityClass genData, boolean generateLocal) throws IOException { 185 FileObject ejbClassFO = pkg.getFileObject(EjbGenerationUtil.getBaseName(e.getEjbClass()), "java"); assert ejbClassFO != null: "interface class "+ e.getLocalHome() + " not found in " + pkg; 187 188 Iterator <EntityMember> it = genData.getFields().iterator(); 189 while (it.hasNext()) { 190 EntityMember em = (EntityMember) it.next(); 191 String type = em.getMemberType(); 192 if (em.supportsFinder()) { String methodName = "findBy" + EntityMember.makeClassName(em.getMemberName()); 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 ejbql = MessageFormat.format( 204 "SELECT OBJECT({0}) " + 205 "FROM {1} AS {0} " + "WHERE {0}.{2} = ?1", new Object [] { 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 227 private void populateEntity(EntityClass bean, Entity e, String wizardTargetName) { 228 if (bean.isUsePkField()) { 229 e.setPrimkeyField(bean.getPkFieldName()); 230 } 231 e.setAbstractSchemaName(wizardTargetName); 232 233 Iterator 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 .class.getName()); 271 } 272 ejbR.setCmrField(f); 273 ejbR.setEjbRelationshipRoleName(role.getEntityName()); 274 } 275 276 private String getCmrFieldType(RelationshipRole role, String pkg) { 277 if (role.isToMany()) { 278 return java.util.Collection .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 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 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 { 306 EJBNameOptions ejbNames = new EJBNameOptions(); 307 String className = ejbNames.getEntityEjbClassPrefix() + entityClass.getClassName() + ejbNames.getEntityEjbClassSuffix(); 308 FileObject ejbClassFO = entityClass.getPackageFileObject().getFileObject(EjbGenerationUtil.getBaseName(className), "java"); 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 326 private void addRelationshipFields(Entity entity, EntityClass entityClass) throws IOException { 327 FileObject ejbClassFO = entityClass.getPackageFileObject().getFileObject(EjbGenerationUtil.getBaseName(entity.getEjbClass()), "java"); CmFieldGenerator generator = CmFieldGenerator.create(entity, ejbClassFO, ddFileObject); 329 for (RelationshipRole role : entityClass.getRoles()) { 330 String 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 className) throws IOException { 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 message); 357 358 } 359 360 } 361 | Popular Tags |