1 27 28 package org.objectweb.speedo.generation.jorm; 29 30 import java.util.ArrayList ; 31 import java.util.Collection ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 import java.util.Set ; 35 36 import org.objectweb.jorm.api.PException; 37 import org.objectweb.jorm.compiler.api.JormCompilerConfigurator; 38 import org.objectweb.jorm.compiler.api.JormCompilerParameter; 39 import org.objectweb.jorm.compiler.lib.JormCompiler; 40 import org.objectweb.jorm.metainfo.api.Class; 41 import org.objectweb.jorm.metainfo.api.ClassProject; 42 import org.objectweb.jorm.metainfo.api.CompositeName; 43 import org.objectweb.jorm.metainfo.api.GenClassRef; 44 import org.objectweb.jorm.metainfo.api.Manager; 45 import org.objectweb.jorm.metainfo.api.Mapping; 46 import org.objectweb.jorm.metainfo.api.NameDef; 47 import org.objectweb.jorm.metainfo.api.TypedElement; 48 import org.objectweb.jorm.util.io.lib.DirJavaExplorer; 49 import org.objectweb.speedo.api.ExceptionHelper; 50 import org.objectweb.speedo.api.SpeedoException; 51 import org.objectweb.speedo.api.SpeedoProperties; 52 import org.objectweb.speedo.generation.api.SpeedoXMLError; 53 import org.objectweb.speedo.generation.lib.AbstractGeneratorComponent; 54 import org.objectweb.speedo.metadata.SpeedoClass; 55 import org.objectweb.speedo.metadata.SpeedoField; 56 import org.objectweb.speedo.metadata.SpeedoIdentity; 57 import org.objectweb.speedo.metadata.SpeedoModifier; 58 import org.objectweb.speedo.metadata.SpeedoPackage; 59 import org.objectweb.speedo.metadata.SpeedoXMLDescriptor; 60 import org.objectweb.util.monolog.api.BasicLevel; 61 62 67 public class JormGenerator extends AbstractGeneratorComponent { 68 69 public final static String LOGGER_NAME 70 = SpeedoProperties.LOGGER_NAME + ".generation.jorm"; 71 72 75 protected JormCompiler jormcompiler; 76 77 78 81 public boolean init() throws SpeedoException { 82 if (scp.getXmldescriptor().isEmpty()) { 83 return false; 84 } 85 logger = scp.loggerFactory.getLogger(LOGGER_NAME); 86 jormcompiler = new JormCompiler(); 87 JormCompilerParameter jcp = jormcompiler.getCompilerParameter(); 88 JormCompilerConfigurator jcc = jormcompiler.getCompilerConfigurator(); 89 try { 90 jcc.configure(); 91 jcp.loadConfFile(jcc.getGlobalJormcOptsFile(), jcc.knownMappers()); 92 jcc.setLoggerFactory(scp.loggerFactory); 93 jcp.setProjectName(scp.projectName); 94 jcp.setBindingInheritance("%p%c"); 95 jcp.setClassMappingInheritance("%p%cHome"); 96 jcp.setOutput(scp.output); 97 jcp.setBindingAbstract(true); 98 jcp.setDtdLocations(scp.dtdLocations); 99 jcp.setInputFiles(scp.jorm); 100 DirJavaExplorer pe = new DirJavaExplorer(); 101 pe.setLogger(scp.loggerFactory.getLogger("org.objectweb.jorm.io.pathexplorer")); 102 pe.addPath(scp.jormclasspath); 103 jcp.setClasspath(pe); 104 jcp.setGenerateBinding(false); 105 jcp.setGeneratedWithMapperPackage(false); 106 int idx = scp.mapperName.indexOf('.'); 107 if (idx == -1) { 108 jcc.removeMapper(scp.mapperName); 109 jcc.addSubMapper(scp.mapperName, "generic"); 110 } else { 111 String actualmn = scp.mapperName.substring(0,idx); 112 jcc.removeMapper(actualmn); 113 jcc.addSubMapper(actualmn, scp.mapperName.substring(idx + 1)); 114 } 115 if (logger.isLoggable(BasicLevel.DEBUG)) { 116 logger.log(BasicLevel.DEBUG, "jormcOpts file:" + jcc.getJormcOptsFile()); 117 Iterator it = jcc.knownMappers(); 118 while(it.hasNext()) { 119 String mapperName = (String ) it.next(); 120 logger.log(BasicLevel.DEBUG, mapperName + " sub mappers: " 121 + jcc.getSubMappers(mapperName )); 122 } 123 } 124 } catch (PException e) { 125 logger.log(BasicLevel.ERROR, 126 "Impossible to configure Jorm", ExceptionHelper.getNested(e)); 127 throw new SpeedoException("Impossible to configure Jorm", e); 128 } 129 return true; 130 } 131 132 135 public void process() throws SpeedoException { 136 if (scp.getXmldescriptor().isEmpty()) { 137 return; 138 } 139 try { 140 Collection pdfiles = jormcompiler.getCompilerParameter().getInputFiles(); 142 if (logger.isLoggable(BasicLevel.DEBUG)) { 143 for (Iterator it = pdfiles.iterator(); it.hasNext();) 144 logger.log(BasicLevel.DEBUG, "source file: " + it.next()); 145 } 146 147 ArrayList notFoundMOs = new ArrayList (); 149 for (Iterator itDesc = scp.getXmldescriptor().values().iterator(); itDesc.hasNext();) { 150 SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc.next(); 151 List scs = desc.getSpeedoClasses(); 152 for (int i=0; i<scs.size(); i++) { 153 SpeedoClass sc = (SpeedoClass) scs.get(i); 154 String fn = sc.getJormFileName(); 155 logger.log(BasicLevel.DEBUG, "looking for the file: " + fn); 156 if (!pdfiles.contains(fn)) { 157 notFoundMOs.add(sc); 159 } 160 } 161 } 162 163 jormcompiler.setupLogger(); 166 jormcompiler.setupMIManager(); 167 Collection createdMOs = null; 168 if (!notFoundMOs.isEmpty()) { 169 createdMOs = new JormMIBuilder( 170 jormcompiler.getMIManager(), scp.nmf, logger) 171 .createMI(notFoundMOs, scp.projectName, scp.mapperName); 172 } 173 174 175 Collection mos = new ArrayList (jormcompiler.parseFiles(pdfiles)); 177 178 isCompatible(); 179 180 if (scp.generateNeededJormFile 182 && createdMOs != null && !createdMOs.isEmpty()) { 183 jormcompiler.generateJormFiles(createdMOs); 184 } 185 mos.addAll(createdMOs); 186 187 if (logger.isLoggable(BasicLevel.DEBUG)) 188 for (Iterator it = mos.iterator(); it.hasNext();) { 189 Object o = it.next(); 190 if (o instanceof Class ) { 191 logger.log(BasicLevel.DEBUG, "Class : " 192 + ((Class ) o).getFQName()); 193 } else if (o instanceof CompositeName) { 194 logger.log(BasicLevel.DEBUG, "compositeName : " 195 + ((CompositeName) o).getFQName()); 196 } else 197 logger.log(BasicLevel.DEBUG, "metaObject : " + o); 198 } 199 200 203 mos = jormcompiler.generateFiles(mos); 205 206 if (logger.isLoggable(BasicLevel.DEBUG)) 207 for (Iterator it = mos.iterator(); it.hasNext();) 208 logger.log(BasicLevel.DEBUG, "Generated files: " + it.next()); 209 210 for (Iterator itDesc = scp.getXmldescriptor().values().iterator(); itDesc.hasNext();) { 212 addSerializeJormMI((SpeedoXMLDescriptor) itDesc.next()); 213 } 214 } catch (PException e) { 215 throw new SpeedoException("Error during Jorm generation", e); 216 } 217 } 218 219 224 protected void isCompatible() throws SpeedoException { 225 226 List except = new ArrayList (); 227 228 Manager manager = jormcompiler.getMIManager(); 229 for (Iterator itDesc = scp.getXmldescriptor().values().iterator(); itDesc.hasNext();) { 230 SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc.next(); 231 List scs = desc.getSpeedoClasses(); 232 for (int i=0; i<scs.size(); i++) { 233 compareClass((SpeedoClass) scs.get(i), manager, except); 234 } 235 } 236 if (!except.isEmpty() && logger.isLoggable(BasicLevel.ERROR)) 237 for (Iterator it = except.iterator(); it.hasNext();) 238 logger.log(BasicLevel.ERROR, it.next()); 239 } 240 241 protected void compareClass(SpeedoClass clas, 242 Manager manager, 243 List except) throws SpeedoException { 244 debug = logger.isLoggable(BasicLevel.DEBUG); 245 if (debug) { 246 logger.log(BasicLevel.DEBUG, 247 "Verify the definition of the class " + clas.getFQName()); 248 } 249 Class classJorm = manager.getClass(clas.getFQName()); 250 if (classJorm == null) { 251 throw new SpeedoException("Jorm description of the class '" 252 + clas.getFQName() + "' is not availlable"); 253 } 254 NameDef pName = null; 255 SpeedoClass sc = clas; 256 while(sc.superClassName != null) { 257 SpeedoClass _sc = sc; 258 sc = sc.jdoPackage.jdoXMLDescriptor.smi.getSpeedoClass(sc.superClassName, sc.jdoPackage); 259 if (sc == null) { 260 throw new SpeedoException("Class " + _sc.getFQName() + " not defined in the jorm meta information"); 261 } 262 } 263 Class pclassJorm = manager.getClass(sc.getFQName()); 264 pName = getClassNameDef(pclassJorm); 265 266 if (classJorm == null) { 267 throw new SpeedoXMLError("Class '" + clas.name + "' not defined in JORM metadata"); 268 } 269 270 clas.jormclass = classJorm; 272 for (Iterator efield = clas.jdoField.values().iterator(); efield.hasNext();) { 273 SpeedoField field = (SpeedoField) efield.next(); 274 String fieldName = field.name; 275 276 if (field.persistenceModifier == SpeedoModifier.none) 278 continue; 279 280 TypedElement tElem = classJorm.getTypedElement(fieldName); 281 if (tElem == null) { 282 throw new SpeedoXMLError("Field '" + fieldName 283 + "' not defined in JORM metadata of the class '" 284 + clas.getFQName() + "'"); 285 } 286 287 if (field.primaryKey) { 289 boolean found = false; 290 for (Iterator it = pName.iterateField(); it.hasNext() && !found;) { 291 found = fieldName.equals(it.next()); 292 } 293 if (!found) { 294 throw new SpeedoXMLError("Field '" + fieldName 295 + "' not defined in Class NameDef's Fields of the class '" 296 + clas.getFQName() + "'"); 297 } 298 } 299 300 if (tElem instanceof GenClassRef && field.jdoTuple == null) 301 throw new SpeedoXMLError("field '" + fieldName + "' should be a tuple in JDO metadata of the class '" + clas.getFQName() + "'"); 302 } 303 304 for (Iterator jormfield = classJorm.getFields().iterator(); jormfield.hasNext();) { 306 TypedElement te = (TypedElement) jormfield.next(); 307 String fieldName = te.getName(); 308 if (!clas.jdoField.containsKey(fieldName) 309 && !isContainerIdField(classJorm, te, clas)) 310 throw new SpeedoXMLError("Field '" + fieldName + "' of the class '" 311 + clas.getFQName() + "' is not defined in the '" 312 + clas.jdoPackage.jdoXMLDescriptor.xmlFile 313 + "' file (found: " + clas.jdoField.keySet() + ")."); 314 } 315 316 if (clas.identityType == SpeedoIdentity.USER_ID) { 318 SpeedoClass classWithId = clas; 319 while(classWithId.superClassName != null) { 320 classWithId = classWithId.getSpeedoClassFromContext(classWithId.superClassName); 321 } 322 boolean found = false; 323 for (Iterator it = pName.iterateField(); it.hasNext() && !found;) { 324 String fn = (String ) it.next(); 325 SpeedoField sf = (SpeedoField) classWithId.jdoField.get(fn); 326 if (sf == null) { 327 logger.log(BasicLevel.WARN, "Field " + fn + " defined in the identifier of " 328 + classWithId.name 329 + ".pd file but not availlable in the class (or .pd file)."); 330 } else if (!sf.primaryKey) { 331 except.add("Field " + fn + " defined in the " 332 + classWithId.name 333 + ".pd file but is not marked as a primary key field in the " 334 + classWithId.jdoPackage.jdoXMLDescriptor.xmlFile 335 + " file."); 336 } 337 } 338 } 339 } 340 341 private boolean isContainerIdField(Class clazz, 342 TypedElement te, 343 SpeedoClass sc) throws SpeedoException { 344 return sc.identityType == SpeedoIdentity.CONTAINER_ID 345 && getClassNameDef(clazz).getNameRef() 346 .getProjection().containsValue(te.getName()); 347 } 348 349 350 private Mapping getMapping(Class clazz) throws SpeedoException { 351 ClassProject cp = clazz.getClassProject(scp.projectName); 352 if (cp == null) { 353 throw new SpeedoException("No classproject found for the class " 354 + clazz.getFQName() + " and the project " + scp.projectName); 355 } 356 int idx = scp.mapperName.indexOf('.'); 357 Mapping m = cp.getMapping(idx == -1 358 ? scp.mapperName 359 : scp.mapperName.substring(0, idx)); 360 if (m == null) { 361 throw new SpeedoException("No mapping found for the class " 362 + clazz.getFQName() + ", the project " + scp.projectName 363 + " and the mapper " + scp.mapperName); 364 } 365 return m; 366 } 367 368 private NameDef getClassNameDef(Class clazz) throws SpeedoException { 369 return (NameDef) getMapping(clazz).getClassMapping() 370 .getIdentifierMapping().getLinkedMO(); 371 } 372 373 private void addSerializeJormMI(SpeedoXMLDescriptor desc) 374 throws SpeedoException { 375 for (Iterator itPack = desc.jdoPackage.values().iterator(); itPack.hasNext();) { 378 SpeedoPackage sp = (SpeedoPackage) itPack.next(); 379 for (Iterator itclass = sp.jdoClass.values().iterator(); itclass.hasNext();) { 380 SpeedoClass jdoClass = (SpeedoClass) itclass.next(); 381 if (jdoClass.jormclass == null) 382 throw new SpeedoException( 383 "The Jorm meta information of the jdo descriptor " 384 + desc.xmlFile + " is not complete: class " 385 + jdoClass.name + " has not been found"); 386 addMOClass(jdoClass.jormclass, desc.mos); 388 389 for (Iterator it = jdoClass.jormclass.getNameDefs().iterator(); it.hasNext();) { 391 NameDef nd = (NameDef) it.next(); 392 if (nd.isNameRef()) { 393 desc.mos.add(nd.getNameRef().getCompositeName()); 394 } 395 } 396 397 } 400 } 401 } 402 403 private void addMOClass(Class mo, Set mos) { 404 mos.add(mo); 405 for(Iterator it = mo.getSuperClasses().iterator();it.hasNext();) { 406 addMOClass((Class ) it.next(), mos); 407 } 408 } 409 } 410 | Popular Tags |