1 19 20 package org.netbeans.modules.j2ee.persistence.dd; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.io.IOException ; 25 import java.lang.ref.WeakReference ; 26 import java.util.ArrayList ; 27 import java.util.Collections ; 28 import java.util.Comparator ; 29 import java.util.HashMap ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.Map ; 34 import java.util.Set ; 35 import java.util.WeakHashMap ; 36 import org.netbeans.api.java.classpath.ClassPath; 37 import org.netbeans.api.project.FileOwnerQuery; 38 import org.netbeans.api.project.Project; 39 import org.netbeans.modules.j2ee.metadata.MetadataUnit; 40 import org.netbeans.modules.j2ee.persistence.api.PersistenceScope; 41 import org.netbeans.modules.j2ee.persistence.api.PersistenceScopes; 42 import org.netbeans.modules.j2ee.persistence.api.metadata.orm.Entity; 43 import org.netbeans.modules.j2ee.persistence.api.metadata.orm.EntityMappings; 44 import org.netbeans.modules.j2ee.persistence.dd.persistence.model_1_0.Persistence; 45 import org.netbeans.modules.j2ee.persistence.dd.persistence.model_1_0.PersistenceUnit; 46 import org.netbeans.modules.j2ee.persistence.spi.PersistenceClassPathProvider; 47 import org.netbeans.modules.j2ee.persistence.unit.PUDataObject; 48 import org.openide.filesystems.FileObject; 49 import org.openide.loaders.DataObject; 50 import org.openide.loaders.DataObjectNotFoundException; 51 import org.openide.util.WeakListeners; 52 53 57 public class PersistenceUtils { 58 59 61 65 private static final Map <FileObject, EntityMappingsCache> persistence2EMCache = new WeakHashMap <FileObject, EntityMappingsCache>(); 66 67 71 private static final WeakHashMap <Project, MetadataUnit> project2MUCache = new WeakHashMap <Project, MetadataUnit>(); 72 73 private PersistenceUtils() { 74 } 75 76 88 public static EntityMappings getEntityMappings(PersistenceScope persistenceScope, String persistenceUnitName) throws IOException { 89 if (persistenceScope == null) { 90 throw new NullPointerException ("The persistenceScope parameter cannot be null"); } 92 if (persistenceUnitName == null) { 93 throw new NullPointerException ("The persistenceUnitName parameter cannot be null"); } 95 96 EntityMappingsCache emCache = getEntityMappingsCache(persistenceScope); 97 if (emCache != null) { 98 return emCache.getEntityMappings(persistenceUnitName); 99 } 100 return null; 101 } 102 103 112 public static List <EntityMappings> getEntityMappings(Project project) throws IOException { 113 if (project == null) { 114 throw new NullPointerException ("The project parameter cannot be null"); } 116 117 List <EntityMappings> result = new ArrayList <EntityMappings>(); 118 for (PersistenceScope persistenceScope : getPersistenceScopes(project)) { 119 EntityMappingsCache emCache = getEntityMappingsCache(persistenceScope); 120 if (emCache != null) { 121 result.addAll(emCache.getEntityMappings()); 122 } 123 } 124 125 return Collections.unmodifiableList(result); 126 } 127 128 136 static EntityMappingsCache getEntityMappingsCache(PersistenceScope persistenceScope) throws IOException { 137 FileObject persistenceXml = persistenceScope.getPersistenceXml(); 138 if (persistenceXml == null) { 139 return null; 140 } 141 142 EntityMappingsCache emCache = null; 143 synchronized (persistence2EMCache) { 144 emCache = persistence2EMCache.get(persistenceXml); 145 if (emCache == null && persistenceXml.isValid()) { 146 emCache = EntityMappingsCache.create(persistenceScope); 147 persistence2EMCache.put(persistenceXml, emCache); 148 } 149 } 150 return emCache; 151 } 152 153 157 private static void removeFromCache(FileObject persistenceXml) { 158 synchronized (persistence2EMCache) { 159 persistence2EMCache.remove(persistenceXml); 160 } 161 } 162 163 172 public static Set <Entity> getEntityClasses(PersistenceScope persistenceScope) throws IOException { 173 if (persistenceScope == null) { 174 throw new NullPointerException ("The persistenceScope parameter cannot be null"); } 176 177 FileObject persistenceXml = persistenceScope.getPersistenceXml(); 178 if (persistenceXml == null) { 179 return Collections.emptySet(); 180 } 181 182 Set <Entity> result = new HashSet <Entity>(); 183 Persistence persistence = PersistenceMetadata.getDefault().getRoot(persistenceXml); 184 for (PersistenceUnit persistenceUnit : persistence.getPersistenceUnit()) { 185 EntityMappings entityMappings = getEntityMappings(persistenceScope, persistenceUnit.getName()); 186 if (entityMappings == null) { 187 continue; 188 } 189 190 for (Entity entity : entityMappings.getEntity()) { 191 result.add(entity); 192 } 193 } 194 195 return Collections.unmodifiableSet(result); 196 } 197 198 209 public static Set <Entity> getEntityClasses(Project project) throws IOException { 210 if (project == null) { 211 throw new NullPointerException ("The project parameter cannot be null"); } 213 214 Set <Entity> result = new HashSet <Entity>(); 215 Set <String > entityNames = new HashSet <String >(); 216 for (PersistenceScope persistenceScope : getPersistenceScopes(project)) { 217 for (Entity entity : getEntityClasses(persistenceScope)) { 219 String entityName = entity.getName(); 220 if (!entityNames.contains(entityName)) { 221 result.add(entity); 222 entityNames.add(entityName); 223 } 224 } 225 } 226 227 return Collections.unmodifiableSet(result); 228 } 229 230 238 public static Set <Entity> getEntityClasses(List <EntityMappings> entityMappingsList) { 239 if (entityMappingsList == null) { 240 throw new NullPointerException ("The entityMappingsList parameter cannot be null"); } 242 243 Set <Entity> result = new HashSet <Entity>(); 244 Set <String > entityNames = new HashSet <String >(); 245 for (EntityMappings em : entityMappingsList) { 246 for (Entity entity : em.getEntity()) { 248 String entityName = entity.getName(); 249 if (!entityNames.contains(entityName)) { 250 result.add(entity); 251 entityNames.add(entityName); 252 } 253 } 254 } 255 256 return Collections.unmodifiableSet(result); 257 } 258 259 269 public static EntityMappings getAnnotationEntityMappings(Project project) { 270 if (project == null) { 271 throw new NullPointerException ("The project parameter cannot be null"); } 273 274 try { 275 return ORMMetadata.getDefault().getRoot(getPersistenceMetadataUnit(project)); 276 } catch (IOException e) { 277 return new org.netbeans.modules.j2ee.persistence.dd.orm.model_1_0.EntityMappings(); 280 } 281 } 282 283 293 public static Set <Entity> getAnnotationEntityClasses(Project project) { 294 Set <Entity> result = new HashSet <Entity>(); 295 for (Entity entity : getAnnotationEntityMappings(project).getEntity()) { 296 result.add(entity); 297 } 298 return result; 299 } 300 301 309 private static MetadataUnit getPersistenceMetadataUnit(Project project) { 310 MetadataUnit mu; 311 synchronized (project2MUCache) { 312 mu = project2MUCache.get(project); 313 if (mu == null) { 314 ClassPath classpath = null; 315 PersistenceClassPathProvider provider = (PersistenceClassPathProvider)project.getLookup().lookup(PersistenceClassPathProvider.class); 316 if (provider != null) { 317 classpath = provider.getClassPath(); 318 } 319 mu = new WeakMetadataUnit(null, classpath); 320 project2MUCache.put(project, mu); 321 } 322 } 323 return mu; 324 } 325 326 335 public static PersistenceUnit[] getPersistenceUnits(FileObject sourceFile) throws IOException { 336 if (sourceFile == null) { 337 throw new NullPointerException ("The sourceFile parameter cannot be null"); } 339 340 Project project = FileOwnerQuery.getOwner(sourceFile); 341 if (project == null) { 342 return new PersistenceUnit[0]; 343 } 344 345 List <PersistenceUnit> result = new ArrayList <PersistenceUnit>(); 346 for (PersistenceScope persistenceScope : getPersistenceScopes(project)) { 347 Persistence persistence = PersistenceMetadata.getDefault().getRoot(persistenceScope.getPersistenceXml()); 348 for (PersistenceUnit persistenceUnit : persistence.getPersistenceUnit()) { 349 result.add(persistenceUnit); 350 } 351 } 352 353 return (PersistenceUnit[])result.toArray(new PersistenceUnit[result.size()]); 354 } 355 356 370 public static EntityMappings getEntityMappings(FileObject sourceFile) { 371 if (sourceFile == null) { 372 throw new NullPointerException ("The sourceFile parameter cannot be null"); } 374 375 Project project = FileOwnerQuery.getOwner(sourceFile); 376 if (project == null) { 377 return null; 378 } 379 380 return getAnnotationEntityMappings(project); 381 } 382 383 391 public static List <Entity> sortEntityClasses(Set <Entity> entityClasses) { 392 if (entityClasses == null) { 393 throw new NullPointerException ("The entityClasses parameter cannot be null"); } 395 List <Entity> entityList = new ArrayList (entityClasses); 396 Collections.sort(entityList, new EntityComparator()); 397 return entityList; 398 } 399 400 401 410 public static Entity getEntity(String className, EntityMappings entityMappings) { 411 if (className == null) { 412 throw new NullPointerException ("The javaClass parameter cannot be null"); } 414 if (entityMappings == null) { 415 throw new NullPointerException ("The entityMappings parameter cannot be null"); } 417 418 for (Entity entity : entityMappings.getEntity()) { 419 if (className.equals(entity.getClass2())) { 420 return entity; 421 } 422 } 423 return null; 424 } 425 426 443 public static PersistenceScope[] getPersistenceScopes(Project project) { 444 if (project == null) { 445 throw new NullPointerException ("The project parameter cannot be null"); } 447 448 PersistenceScopes persistenceScopes = PersistenceScopes.getPersistenceScopes(project); 449 if (persistenceScopes != null) { 450 return persistenceScopes.getPersistenceScopes(); 451 } 452 return new PersistenceScope[0]; 453 } 454 455 459 static final class EntityMappingsCache implements PropertyChangeListener { 460 461 private final WeakReference <PersistenceScope> persistenceScopeRef; 462 463 private final Map <String , WeakMetadataUnit> metadataUnitCache = new HashMap <String , WeakMetadataUnit>(); 464 465 471 public static EntityMappingsCache create(PersistenceScope persistenceScope) { 472 EntityMappingsCache result = new EntityMappingsCache(persistenceScope); 473 result.startListening(); 474 return result; 475 } 476 477 private EntityMappingsCache(PersistenceScope persistenceScope) { 478 persistenceScopeRef = new WeakReference <PersistenceScope>(persistenceScope); 479 } 480 481 private void startListening() { 482 PUDataObject pudo = getPUDataObject(); 483 if (pudo != null) { 484 pudo.addPropertyChangeListener(WeakListeners.propertyChange(this, pudo)); 485 } 486 } 487 488 public EntityMappings getEntityMappings(String persistenceUnitName) throws IOException { 489 MetadataUnit mu = getMetadataUnit(persistenceUnitName); 490 if (mu != null) { 491 return ORMMetadata.getDefault().getRoot(mu); 492 } else { 493 return null; 494 } 495 } 496 497 500 public List <EntityMappings> getEntityMappings() throws IOException { 501 PUDataObject pudo = getPUDataObject(); 502 if (pudo == null) { 503 return Collections.emptyList(); 504 } 505 506 List <EntityMappings> entityMappingsList = new ArrayList <EntityMappings>(); 507 508 Persistence persistence = pudo.getPersistence(); 509 synchronized (this) { 510 for (PersistenceUnit persistenceUnit : persistence.getPersistenceUnit()) { 511 EntityMappings em = getEntityMappings(persistenceUnit.getName()); 512 if (em != null) { 513 entityMappingsList.add(em); 514 } 515 } 516 } 517 518 return Collections.unmodifiableList(entityMappingsList); 519 } 520 521 525 MetadataUnit getMetadataUnit(String persistenceUnitName) { 526 PersistenceScope persistenceScope = persistenceScopeRef.get(); 527 if (persistenceScope == null) { 528 return null; 529 } 530 531 WeakMetadataUnit metadataUnit = null; 532 synchronized (this) { 533 metadataUnit = metadataUnitCache.get(persistenceUnitName); 534 if (metadataUnit == null) { 535 PUDataObject pudo = getPUDataObject(); 536 if (pudo != null) { 537 metadataUnit = createMetadataUnit(pudo, persistenceScope.getClassPath(), persistenceUnitName); 538 if (metadataUnit != null) { 539 metadataUnitCache.put(persistenceUnitName, metadataUnit); 540 } 541 } 542 } 543 } 544 545 return metadataUnit; 546 } 547 548 private WeakMetadataUnit createMetadataUnit(PUDataObject pudo, ClassPath classPath, String persistenceUnitName) { 549 assert Thread.holdsLock(this); 550 551 Persistence persistence = pudo.getPersistence(); 552 for (PersistenceUnit unit : persistence.getPersistenceUnit()) { 553 if (persistenceUnitName.equals(unit.getName())) { 554 return new WeakMetadataUnit(getMappingFile(pudo), classPath); 555 } 556 } 557 return null; 558 } 559 560 566 private void refreshCache() { 567 PUDataObject pudo = getPUDataObject(); 568 if (pudo == null) { 569 return; 570 } 571 572 Persistence persistence = pudo.getPersistence(); 573 synchronized (this) { 574 Set <String > persistenceUnitNames = new HashSet <String >(); 575 for (PersistenceUnit persistenceUnit : persistence.getPersistenceUnit()) { 576 persistenceUnitNames.add(persistenceUnit.getName()); 577 } 578 579 for (Iterator <Map.Entry <String , WeakMetadataUnit>> i = metadataUnitCache.entrySet().iterator(); i.hasNext();) { 581 if (!persistenceUnitNames.contains(i.next().getKey())) { 582 i.remove(); 583 } 584 } 585 586 for (PersistenceUnit persistenceUnit : persistence.getPersistenceUnit()) { 588 WeakMetadataUnit metadataUnit = metadataUnitCache.get(persistenceUnit.getName()); 590 if (metadataUnit == null) { 591 continue; 593 } 594 595 refreshMetadataUnit(metadataUnit, pudo); 596 } 597 } 598 } 599 600 private static void refreshMetadataUnit(WeakMetadataUnit metadataUnit, PUDataObject pudo) { 601 metadataUnit.setDeploymentDescriptor(getMappingFile(pudo)); 602 } 603 604 private static FileObject getMappingFile(PUDataObject pudo) { 605 608 FileObject persistenceXml = pudo.getPrimaryFile(); 609 FileObject ormXml = null; 610 if (persistenceXml != null) { 611 FileObject metaInf = persistenceXml.getParent(); 612 if (metaInf != null) { 613 ormXml = metaInf.getFileObject("orm.xml"); } 615 } 616 return ormXml; 617 } 618 619 PUDataObject getPUDataObject() { 620 PersistenceScope persistenceScope = persistenceScopeRef.get(); 621 FileObject persistenceXml = null; 622 if (persistenceScope != null) { 623 persistenceXml = persistenceScope.getPersistenceXml(); 624 } 625 626 if (persistenceXml == null) { 627 return null; 628 } 629 630 try { 631 return (PUDataObject)DataObject.find(persistenceXml); 632 } catch (DataObjectNotFoundException e) { 633 return null; 634 } 635 } 636 637 public void propertyChange(PropertyChangeEvent evt) { 638 if (DataObject.PROP_VALID.equals(evt.getPropertyName())) { 639 removeFromCache(((DataObject)evt.getSource()).getPrimaryFile()); 640 } else { 641 refreshCache(); 642 } 643 } 644 } 645 646 649 private static final class EntityComparator implements Comparator <Entity> { 650 651 public int compare(Entity o1, Entity o2) { 652 String name1 = o1.getClass2(); 653 String name2 = o2.getClass2(); 654 if (name1 == null) { 655 return name2 == null ? 0 : -1; 656 } else { 657 return name2 == null ? 1 : name1.compareTo(name2); 658 } 659 } 660 } 661 } 662 | Popular Tags |