1 18 package org.objectweb.speedo.naming.lib; 19 20 import org.objectweb.perseus.cache.api.CacheManager; 21 import org.objectweb.speedo.naming.api.NamingManager; 22 import org.objectweb.speedo.naming.api.MIBuilderHelper; 23 import org.objectweb.speedo.pm.api.ProxyManagerFactory; 24 import org.objectweb.jorm.facility.naming.longid.LongIdManager; 25 import org.objectweb.jorm.facility.naming.longid.LongIdBinder; 26 import org.objectweb.jorm.facility.naming.longid.LongIdPName; 27 import org.objectweb.jorm.facility.naming.longid.LongIdPNC; 28 import org.objectweb.speedo.metadata.SpeedoClass; 29 import org.objectweb.speedo.metadata.SpeedoIdentity; 30 import org.objectweb.speedo.metadata.SpeedoExtension; 31 import org.objectweb.speedo.metadata.SpeedoField; 32 import org.objectweb.speedo.api.SpeedoProperties; 33 import org.objectweb.speedo.api.SpeedoException; 34 import org.objectweb.speedo.mapper.api.JormFactory; 35 import org.objectweb.speedo.generation.jorm.JormMIMappingBuilder; 36 import org.objectweb.speedo.generation.lib.NamingRules; 37 import org.objectweb.util.monolog.api.Logger; 38 import org.objectweb.util.monolog.api.BasicLevel; 39 import org.objectweb.jorm.naming.api.PName; 40 import org.objectweb.jorm.naming.api.PNameCoder; 41 import org.objectweb.jorm.naming.api.PBinder; 42 import org.objectweb.jorm.naming.api.PNamingContext; 43 import org.objectweb.jorm.api.PClassMapping; 44 import org.objectweb.jorm.api.PException; 45 import org.objectweb.jorm.api.PMapper; 46 import org.objectweb.jorm.metainfo.api.NameDef; 47 import org.objectweb.jorm.metainfo.api.MetaObject; 48 import org.objectweb.jorm.metainfo.api.Manager; 49 import org.objectweb.jorm.metainfo.api.Reference; 50 import org.objectweb.jorm.metainfo.api.CommonClassMapping; 51 import org.objectweb.jorm.metainfo.api.GenClassRef; 52 import org.objectweb.jorm.metainfo.api.PrimitiveElement; 53 import org.objectweb.jorm.metainfo.api.CompositeName; 54 import org.objectweb.jorm.metainfo.api.NameRef; 55 import org.objectweb.jorm.metainfo.api.ScalarField; 56 import org.objectweb.jorm.type.api.PTypeSpace; 57 import org.objectweb.jorm.type.api.PType; 58 import org.objectweb.medor.expression.api.Expression; 59 import org.objectweb.medor.expression.api.ExpressionException; 60 import org.objectweb.medor.expression.lib.DivideBy; 61 import org.objectweb.medor.expression.lib.BasicOperand; 62 import org.objectweb.medor.expression.lib.BasicParameterOperand; 63 import org.objectweb.medor.expression.lib.Round; 64 65 import java.util.Properties ; 66 import java.util.Map ; 67 import java.util.Collection ; 68 import java.util.Iterator ; 69 import java.util.ArrayList ; 70 71 75 public class LongIdNamingManager 76 extends LongIdManager 77 implements NamingManager { 78 79 private final static String _LONG_ID_NAME 80 = "org.objectweb.jorm.facility.naming.longid.LongId"; 81 private final static String _LONG_ID_LID = "lid"; 82 private final static String BINDER_FOR_CLASS = "c"; 83 private final static String BINDER_FOR_GENCLASS = "gc"; 84 private final static String HIDDEN_LID_FIELD_NAME = "jdolid"; 85 86 private Logger logger; 87 private PMapper mapper; 88 private ProxyManagerFactory pmf; 89 90 protected String LONG_ID_NAME() { 91 return _LONG_ID_NAME; 92 } 93 94 protected String LONG_ID_LID() { 95 return _LONG_ID_LID; 96 } 97 98 protected PType getFieldType() { 99 return PTypeSpace.LONG; 100 } 101 102 protected BasicOperand getBasicOperand() { 103 return new BasicOperand(1l << 44); 104 } 105 106 protected boolean checkFieldType(String type) { 107 return "long".equals(type); 108 } 109 110 111 public void init() throws PException { 112 if (getMapper() != null) { 113 return; 114 } 115 if (mapper == null) { 116 throw new PException("No mapper assigned"); 117 } 118 super.setPMapper(mapper); 119 mapper = null; 120 } 121 122 public void setPMapper(PMapper mapper) throws PException { 125 this.mapper = mapper; 126 } 127 128 public void setPmf(ProxyManagerFactory pmf) { 129 130 } 131 132 public boolean supportPNamingcontext() { 133 return true; 134 } 135 136 public boolean canManage(SpeedoClass sc) { 137 if (sc.identityType == SpeedoIdentity.CONTAINER_ID && sc.datastoreSequence == null) { 138 SpeedoExtension se = sc.getExtension( 139 SpeedoProperties.VENDOR_NAME, SpeedoProperties.ID); 140 return se != null 141 && SpeedoProperties.ID_LONG.equalsIgnoreCase(se.value); 142 } else { 143 return false; 144 } 145 } 146 147 public boolean canProvidePBinder(Object hints, ClassLoader classLoader) { 148 return NamingManagerHelper 149 .getBinderClassNameFromHints(hints, LONG_ID_LID()) != null; 150 } 151 152 public boolean canProvidePNamingContext(Object hints, ClassLoader classLoader) { 153 return NamingManagerHelper 154 .getPNCClassNameFromHints(hints, LONG_ID_LID()) != null; 155 } 156 157 public Object encode(PName pn) throws PException { 158 if (pn instanceof LongIdPName) { 159 return pn.getPNameManager().getPType().getJormName() 160 + SEP + pn.encodeLong(); 161 } 162 return null; 163 } 164 165 public PName decode(PNameCoder pnc, 166 Object oid, 167 Class clazz, 168 JormFactory jf) throws PException { 169 if (oid instanceof String ) { 170 String stroid = (String ) oid; 171 int idx = stroid.indexOf(SEP); 172 if (pnc != null) { 173 if (pnc instanceof LongIdBinder 174 || pnc instanceof LongIdManager) { 175 String idStr = stroid; 176 if (idx != -1) { 177 idStr = stroid.substring(idx + SEP.length()); 179 } 180 return pnc.decodeLong(Long.parseLong(idStr)); 181 182 } else { 183 return null; 185 } 186 } else { 187 if (idx != -1) { 189 String fqcn = stroid.substring(0, idx); 191 ClassLoader cl = getClass().getClassLoader(); 192 if (cl == null) { 193 cl = ClassLoader.getSystemClassLoader(); 194 } 195 try { 196 pnc = jf.getPNamingContext(fqcn, cl); 197 } catch (Exception e) { 198 return null; 199 } 200 if (pnc instanceof LongIdBinder 201 || pnc instanceof LongIdPNC) { 202 return pnc.decodeLong( 203 Long.parseLong( 204 stroid.substring(idx + SEP.length()))); 205 } else { 206 return null; 207 } 208 } else { 209 return null; 211 } 212 } 213 } 214 return null; 215 } 216 217 public void setLogger(Logger logger) { 218 this.logger = logger; 219 } 220 221 public String getPNameHints(SpeedoClass sc, NameDef nd) { 222 return "null"; 223 } 224 225 public String getGCPNameHints(SpeedoClass sc, NameDef nd) { 226 return "new Long(proxy.getPName().encodeLong())"; 227 } 228 229 public NamingManager.NamingField[] getNamingfields(SpeedoClass sc) { 230 Iterator it = sc.jdoField.values().iterator(); 231 while (it.hasNext()) { 232 SpeedoField sf = (SpeedoField) it.next(); 233 if (sf.primaryKey) { 234 return new NamingField[]{ 235 new NamingField(sf.name, Long.TYPE, "lid", PTypeSpace.LONG)}; 236 } 237 } 238 return null; 239 } 240 241 public void fillNameDef(MIBuilderHelper mibh, 242 Manager manager, 243 NameDef nd, 244 SpeedoClass tsc, 245 SpeedoClass ssc, 246 MetaObject mo, 247 Reference ref, 248 CommonClassMapping hcm, 249 JormMIMappingBuilder mb, 250 boolean isIdentifier, 251 boolean isInGenClass, 252 boolean createField, 253 Collection createdMOs) throws SpeedoException, PException { 254 SpeedoField sf = fetchUniqueLongPKField(tsc); 255 boolean debug = logger.isLoggable(BasicLevel.DEBUG); 256 if (debug) { 257 logger.log(BasicLevel.DEBUG, "LongIdNaming: Filling the name def: " 258 + "\n\tsource class=" + (ssc == null ? null : ssc.getFQName()) 259 + "\n\ttarget class=" + (tsc == null ? null : tsc.getFQName()) 260 + "\n\tmo=" + mo 261 + "\n\treference=" + ref 262 + "\n\tisIdentifier=" + isIdentifier 263 + "\n\tisInGenClass=" + isInGenClass 264 + "\n\tcreateField=" + createField 265 + "\n\tsf=" + sf); 266 } 267 PrimitiveElement lid; 268 String lidname; 269 if (isInGenClass || sf == null || !isIdentifier) { 270 String prefix = mibh.getNameDefFieldPrefix(ref, isIdentifier, isInGenClass); 271 lidname = prefix + HIDDEN_LID_FIELD_NAME; 272 } else { 273 createField = false; 274 lidname = sf.name; 275 } 276 logger.log(BasicLevel.DEBUG, "lidname=" + lidname); 277 if (createField) { 278 lid = mibh.createNameDefField(mo, lidname, PTypeSpace.LONG); 279 } else { 280 lid = mibh.getPrimitiveField(mo, lidname); 281 if (lid == null) { 282 throw new SpeedoException( 283 mibh.getErrorMessage(tsc, mo, ref) 284 + " Impossible to get the field '" + lidname + "'"); 285 } 286 } 287 if ((isInGenClass && isIdentifier) 288 || (!isIdentifier && !isInGenClass && ref instanceof GenClassRef)) { 289 nd.setFieldName(lidname); 291 } else { 292 CompositeName cn = manager.getCompositeName(LONG_ID_NAME()); 295 if (cn == null) { 296 cn = manager.createCompositeName(LONG_ID_NAME()); 297 ScalarField cnf = cn.createCompositeNameField( 298 LONG_ID_LID(), getFieldType(), PType.NOSIZE, PType.NOSIZE); 299 cnf.setIsAutoCalculated(true); 300 } 301 NameRef nr = nd.createNameRef(cn); 303 nr.addProjection(LONG_ID_LID(), lid.getName()); 304 if (isIdentifier) { 305 assignDummyKeyToFamilly(ssc.jormclass, nd); 306 if (ssc.jormclass.getSuperClasses().isEmpty()) { 307 Expression expr = new Round(new DivideBy( 308 new BasicParameterOperand(getFieldType(), LONG_ID_LID()), 309 getBasicOperand())); 310 try { 311 expr.compileExpression(); 312 } catch (ExpressionException e) { 313 throw new SpeedoException("Impossible to compile the filter of longid naming", e); 314 } 315 ssc.jormclass.setInheritanceFilter(nd, expr); 316 } 317 } 318 } 319 if (mb != null && createField) { 320 mb.createNameDefMapping(hcm, nd, ssc, isIdentifier, isInGenClass); 321 } 322 } 323 324 private void assignDummyKeyToFamilly(org.objectweb.jorm.metainfo.api.Class clazz, NameDef nd) { 325 clazz.setInheritanceNamingKey(nd, "0"); 326 for(Iterator it = clazz.getSubClasses().iterator(); it.hasNext();) { 327 assignDummyKeyToFamilly(((org.objectweb.jorm.metainfo.api.Class) it.next()), nd); 328 } 329 } 330 331 private SpeedoField fetchUniqueLongPKField(SpeedoClass tsc) throws SpeedoException { 332 Iterator it = tsc.jdoField.values().iterator(); 333 SpeedoField sf = null; 334 ArrayList al = null; 335 while (it.hasNext()) { 336 SpeedoField _sf = (SpeedoField) it.next(); 337 if (_sf.primaryKey) { 338 if (sf != null) { 339 if (al == null) { 340 al = new ArrayList (); 341 } 342 al.add(_sf.name); 343 } else { 344 sf = _sf; 345 } 346 } 347 } 348 if (al != null) { 349 al.add(sf); 350 throw new SpeedoException( 351 "Impossible to use an auto incremented identifier if " + 352 "several fields have been marked as primary-key " + al 353 + " in the class '" + tsc.getFQName() + "'."); 354 } 355 if (sf != null) { 356 String t = sf.type(); 357 358 if (!checkFieldType(t)) { 359 throw new SpeedoException( 360 "Impossible to use an auto incremented identifier: " + 361 "the field type of '" + sf.name + "' is '" + sf.type() 362 + "' and '" + getFieldType().getJavaName() 363 + "' is expected (class '" 364 + tsc.getFQName() + "'."); 365 } 366 } 367 return sf; 368 } 369 370 public void getJormNamingConfig(NameDef nd, 371 SpeedoClass targetClass, 372 MetaObject sourceMO, 373 String key, 374 Properties result) { 375 376 StringBuffer sb = new StringBuffer (); 377 sb.append(LONG_ID_LID()); 378 sb.append(NamingManagerHelper.HINTS_SEP); 379 boolean isGCR = sourceMO instanceof GenClassRef; 380 String binderInfo = (isGCR ? BINDER_FOR_GENCLASS : BINDER_FOR_CLASS); 381 sb.append(binderInfo); 382 383 SpeedoClass ancestor = targetClass.getAncestor(); 384 String ancestorClassName; 385 String pncClassName; 386 if (!isGCR && (ancestor != null || !targetClass.jormclass.getSubClasses().isEmpty()) ) { 390 if (ancestor == null) { 391 ancestor = targetClass; 392 } 393 ancestorClassName = ancestor.getFQName(); 394 pncClassName = NamingRules.kfpncName(ancestorClassName); 395 } else { 396 ancestorClassName = targetClass.getFQName(); 397 pncClassName = binderInfo; 398 } 399 sb.append(NamingManagerHelper.HINTS_SEP); 401 sb.append(pncClassName); 402 403 sb.append(NamingManagerHelper.HINTS_SEP); 405 sb.append(ancestorClassName); 406 result.setProperty(key, sb.toString()); 407 } 408 409 public PBinder getPBinder(String className, 410 String hints, 411 ClassLoader classLoader, 412 byte mappingStructureRule, 413 Map cn2binder, 414 Map cn2pnc) throws PException { 415 init(); 416 String binderInfo = NamingManagerHelper.getBinderClassNameFromHints(hints, LONG_ID_LID()); 417 return getPBinder(className, binderInfo); 418 } 419 420 public PNamingContext getPNamingContext(String className, 421 String hints, 422 ClassLoader classLoader, 423 byte mappingStructureRule, 424 Map cn2binder, 425 Map cn2pnc, 426 Manager miManager, 427 PClassMapping pcm) throws PException { 428 init(); 429 String [] tokens = NamingManagerHelper.getTokens(hints); 430 PNamingContext pnc = null; 431 if (tokens[NamingManagerHelper.BINDER_IDX].equals(tokens[NamingManagerHelper.PNC_IDX])) { 432 pnc = (PNamingContext) cn2binder.get(className); 434 if (pnc == null) { 435 pnc = (PNamingContext) getPBinder( 437 className, tokens[NamingManagerHelper.BINDER_IDX]); 438 cn2binder.put(className, pnc); 440 } 441 return pnc; 442 } else { 443 boolean register = false; 444 if (!tokens[NamingManagerHelper.PCLASS_IDX].equals(className)) { 445 pnc = (PNamingContext) cn2pnc.get(tokens[NamingManagerHelper.PCLASS_IDX]); 447 if (pnc == null) { 448 register = true; 449 } 450 } 451 if (pnc == null) { 452 pnc = newClassPNamingContext(); 454 if (register) { 455 cn2pnc.put(tokens[NamingManagerHelper.PCLASS_IDX], pnc); 456 } 457 } 458 } 459 return pnc; 460 } 461 462 private PBinder getPBinder(String className, String binderInfo) throws PException { 463 if (binderInfo.startsWith(BINDER_FOR_GENCLASS)) { 464 return newGenClassPBinder(); 465 } else if (binderInfo.startsWith(BINDER_FOR_CLASS)) { 466 return newClassPBinder(className, null); 467 } else { 468 throw new PException("Bad binder info: " + binderInfo); 469 } 470 } 471 472 public void setCache(CacheManager cache) { 473 } 474 } 475 | Popular Tags |