1 21 package oracle.toplink.essentials.ejb.cmp3.persistence; 23 24 import java.net.URL ; 25 import java.net.URI ; 26 import java.net.URISyntaxException ; 27 import java.util.jar.JarInputStream ; 28 import java.util.zip.ZipEntry ; 29 import java.util.Enumeration ; 30 import java.io.File ; 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 import java.io.FileInputStream ; 34 import java.io.FileNotFoundException ; 35 import java.util.List ; 36 import java.util.Vector ; 37 import java.util.Iterator ; 38 import java.util.Set ; 39 import java.util.HashSet ; 40 41 import javax.xml.parsers.SAXParser ; 42 import javax.xml.parsers.SAXParserFactory ; 43 import javax.persistence.spi.PersistenceUnitInfo; 44 45 import org.xml.sax.XMLReader ; 46 import org.xml.sax.InputSource ; 47 48 import oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException; 49 import oracle.toplink.essentials.exceptions.XMLParseException; 50 import oracle.toplink.essentials.internal.ejb.cmp3.xml.XMLConstants; 51 import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.PersistenceContentHandler; 52 import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XMLException; 53 import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XMLExceptionHandler; 54 import oracle.toplink.essentials.logging.AbstractSessionLog; 55 56 62 public class PersistenceUnitProcessor { 63 64 public static final String JAR_OPENING_EXCEPTION = "attempted_to_open_url_as_jar"; 65 public static final String DIRECTORY_OPENING_EXCEPTION = "attempted_to_open_url_as_directory"; 66 public static final String JAR_ENTRY_OPENING_EXCEPTION = "attempted_to_open_entry_in_url_as_jar"; 67 public static final String DIRECTORY_ENTRY_OPENING_EXCEPTION = "attempted_to_open_file_url_as_directory"; 68 69 76 public static List <SEPersistenceUnitInfo> getPersistenceUnits(URL url, ClassLoader loader){ 77 return processPersistenceArchive(url, loader); 78 } 79 80 81 86 protected static List <SEPersistenceUnitInfo> processPersistenceArchveFromUnconvertableURL(URL baseURL, ClassLoader loader){ 87 InputStream stream = null; 88 try{ 89 stream = baseURL.openStream(); 90 return processPersistenceXML(baseURL, stream, loader); 91 92 } catch (IOException exc){ 93 throw PersistenceUnitLoadingException.exceptionLoadingFromUrl(baseURL.toString(), exc); 94 } finally { 95 try{ 96 if (stream != null){ 97 stream.close(); 98 } 99 } catch (IOException exc){}; 100 101 } 102 } 103 104 110 private static List <SEPersistenceUnitInfo> processDirectory(URL baseURL, File file, ClassLoader loader){ 111 FileInputStream inputStream = null; 112 try{ 113 String filePath = file.getPath(); 114 File persistenceXMLFile = new File (filePath + File.separator + "META-INF" + File.separator + "persistence.xml"); 115 116 if (!persistenceXMLFile.exists()){ 117 persistenceXMLFile = new File (filePath + File.separator + "meta-inf" + File.separator + "persistence.xml"); 118 } 119 if (persistenceXMLFile.exists()){ 120 inputStream = new FileInputStream (persistenceXMLFile); 121 return processPersistenceXML(baseURL, inputStream, loader); 122 } 123 return null; 124 } catch (FileNotFoundException exc){ 125 throw PersistenceUnitLoadingException.exceptionLoadingFromDirectory(file, exc); 126 } finally { 127 try{ 128 if (inputStream != null){ 129 inputStream.close(); 130 } 131 } catch (IOException exc){}; 132 133 } 134 } 135 136 142 protected static List <SEPersistenceUnitInfo> processJarFile(URL baseURL, ClassLoader loader){ 143 JarInputStream jarFile = null; 144 InputStream stream = null; 145 try{ 146 stream = createInputStreamForURL(baseURL); 147 jarFile = new JarInputStream (stream); 148 ZipEntry entry = jarFile.getNextEntry(); 149 while (entry != null && !entry.getName().equals("META-INF/persistence.xml") && !entry.getName().equals("meta-inf/persistence.xml")){ 150 entry = jarFile.getNextEntry(); 151 } 152 if (entry != null && (entry.getName().equals("META-INF/persistence.xml") || entry.getName().equals("meta-inf/persistence.xml"))){ 153 return processPersistenceXML(baseURL, jarFile, loader); 154 } 155 return null; 156 } catch (IOException exc){ 157 throw PersistenceUnitLoadingException.exceptionLoadingFromJar(baseURL, exc); 158 } finally { 159 try{ 160 if (jarFile != null){ 161 jarFile.close(); 162 } 163 if (stream != null){ 164 stream.close(); 165 } 166 } catch (IOException exc){}; 167 168 } 169 } 170 171 174 private static List <SEPersistenceUnitInfo> processPersistenceArchive(URL url, ClassLoader loader){ 175 File file = null; 176 List <SEPersistenceUnitInfo> persistenceUnitList = null; 177 URL tempURL = truncateURLAndRemoveFileReference(url); 180 try{ 181 persistenceUnitList = processJarFile(tempURL, loader); 182 if (persistenceUnitList != null){ 183 return persistenceUnitList; 184 } 185 } catch (Exception exception){ 186 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, JAR_OPENING_EXCEPTION, url, exception); 187 }; 188 189 try{ 190 file = new File (convertURLToURI(tempURL)); 192 if (file.isDirectory()){ 193 persistenceUnitList = processDirectory(tempURL, file, loader); 194 if (persistenceUnitList != null){ 195 return persistenceUnitList; 196 } 197 } 198 } catch (Exception exception){ 199 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, DIRECTORY_OPENING_EXCEPTION, url, exception); 200 }; 201 202 persistenceUnitList = processPersistenceArchveFromUnconvertableURL(url, loader); 203 204 return persistenceUnitList; 205 } 206 207 215 public static InputStream createInputStreamForFileInPersistenceUnit(String fileName, PersistenceUnitInfo persistenceUnitInfo, ClassLoader classLoader) throws IOException { 216 InputStream stream = null; 217 try{ 218 stream = createInputStreamForJarFile(fileName, persistenceUnitInfo.getPersistenceUnitRootUrl()); 219 if (stream != null){ 220 return stream; 221 } 222 } catch (Exception e){ 223 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, JAR_ENTRY_OPENING_EXCEPTION, persistenceUnitInfo.getPersistenceUnitRootUrl(), fileName, e); 224 }; 225 226 try { 227 File file = new File (convertURLToURI(persistenceUnitInfo.getPersistenceUnitRootUrl())); 229 if (file.isDirectory()){ 230 stream = createInputStreamForDirectory(fileName, file); 231 if (stream != null){ 232 return stream; 233 } 234 } 235 } catch (Exception e){ 236 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, DIRECTORY_ENTRY_OPENING_EXCEPTION, persistenceUnitInfo.getPersistenceUnitRootUrl(), fileName, e); 237 }; 238 239 return createInputStreamForUnconvertableURL(fileName, persistenceUnitInfo.getPersistenceUnitRootUrl(), classLoader); 240 } 241 242 245 public static InputStream createInputStreamForJarFile(String fileName, URL url) throws IOException { 246 JarInputStream jarInputStream = new JarInputStream (createInputStreamForURL(url)); 247 248 ZipEntry entry = jarInputStream.getNextEntry(); 249 while (entry != null && !entry.getName().equals(fileName)){ 250 entry = jarInputStream.getNextEntry(); 251 } 252 if (entry != null && (entry.getName().equals(fileName))){ 253 return jarInputStream; 254 } 255 return null; 256 } 257 258 261 public static InputStream createInputStreamForDirectory(String fileName, File inputFile) throws IOException { 262 String filePath = inputFile.getPath(); 263 String tempFileName = fileName; 264 if (!filePath.endsWith(File.separator) && !fileName.startsWith(File.separator)){ 265 tempFileName = File.separator + tempFileName; 266 } 267 268 File xmlFile = new File (filePath + tempFileName); 269 if (xmlFile.exists()){ 270 return new FileInputStream (xmlFile); 271 } 272 return null; 273 } 274 275 282 public static InputStream createInputStreamForUnconvertableURL(String fileName, URL url, ClassLoader loader) throws IOException { 283 String persistenceUnitRoolUrlString = url.toString(); 284 Enumeration <URL > resources = loader.getResources(fileName); 285 while (resources.hasMoreElements()){ 286 URL mappingFileResource = resources.nextElement(); 287 String mappingFileResourceString = mappingFileResource.toString(); 288 if(mappingFileResourceString.contains(persistenceUnitRoolUrlString)) { 289 return url.openStream(); 290 } 291 } 292 return null; 293 } 294 295 301 public static InputStream createInputStreamForURL(URL url) throws IOException { 302 InputStream stream = null; 303 IOException initialException = null; 304 try{ 305 stream = url.openStream(); 307 } catch (IOException exc){ 308 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, JAR_OPENING_EXCEPTION, url, exc); 309 initialException = exc; 310 try{ 311 stream = createTruncatedJarURLFromString(url.toString()).openStream(); 313 } catch (PersistenceUnitLoadingException exception){ 314 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, JAR_OPENING_EXCEPTION, url, exception); 315 throw initialException; 316 } catch (IOException exception2){ 317 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, JAR_OPENING_EXCEPTION, url, exception2); 318 throw initialException; 319 } 320 } 321 return stream; 322 } 323 324 328 public static List <SEPersistenceUnitInfo> processPersistenceXML(URL baseURL, InputStream input, ClassLoader loader){ 329 SAXParserFactory spf = SAXParserFactory.newInstance(); 330 spf.setNamespaceAware(true); 331 spf.setValidating(true); 332 333 XMLReader xmlReader = null; 334 SAXParser sp = null; 335 XMLExceptionHandler xmlErrorHandler = new XMLExceptionHandler(); 336 337 try { 339 sp = spf.newSAXParser(); 340 sp.setProperty(XMLConstants.SCHEMA_LANGUAGE, XMLConstants.XML_SCHEMA); 341 } catch (javax.xml.parsers.ParserConfigurationException exc){ 342 throw XMLParseException.exceptionCreatingSAXParser(baseURL, exc); 343 } catch (org.xml.sax.SAXException exc){ 344 throw XMLParseException.exceptionCreatingSAXParser(baseURL, exc); 345 } 346 347 try { 349 xmlReader = sp.getXMLReader(); 350 xmlReader.setErrorHandler(xmlErrorHandler); 351 } catch (org.xml.sax.SAXException exc){ 352 throw XMLParseException.exceptionCreatingXMLReader(baseURL, exc); 353 } 354 355 URL schemaURL = loader.getResource(XMLConstants.PERSISTENCE_SCHEMA_NAME); 357 if (schemaURL != null) { 358 try { 359 sp.setProperty(XMLConstants.JAXP_SCHEMA_SOURCE, schemaURL.toString()); 360 } catch (org.xml.sax.SAXException exc){ 361 throw XMLParseException.exceptionSettingSchemaSource(baseURL, schemaURL, exc); 362 } 363 } 364 365 PersistenceContentHandler myContentHandler = new PersistenceContentHandler(); 366 xmlReader.setContentHandler(myContentHandler); 367 368 InputSource inputSource = new InputSource (input); 369 try{ 370 xmlReader.parse(inputSource); 371 } catch (IOException exc){ 372 throw PersistenceUnitLoadingException.exceptionProcessingPersistenceXML(baseURL, exc); 373 } catch (org.xml.sax.SAXException exc){ 374 } 376 377 XMLException xmlError = xmlErrorHandler.getXMLException(); 379 if (xmlError != null) { 380 throw PersistenceUnitLoadingException.exceptionProcessingPersistenceXML(baseURL, xmlError); 381 } 382 383 Iterator <SEPersistenceUnitInfo> persistenceInfos = myContentHandler.getPersistenceUnits().iterator(); 384 while (persistenceInfos.hasNext()){ 385 SEPersistenceUnitInfo info = persistenceInfos.next(); 386 info.setPersistenceUnitRootUrl(baseURL); 387 } 388 return myContentHandler.getPersistenceUnits(); 389 } 390 391 394 private static URL truncateURLAndRemoveFileReference(URL url) { 395 String newURLString = url.toString().substring(0, url.toString().length() - 25); 396 return createTruncatedJarURLFromString(newURLString); 397 398 } 399 400 409 private static URL createTruncatedJarURLFromString(String url){ 410 try{ 411 String cleanUrl = url; 412 int index = url.lastIndexOf('!'); 413 if (index > 0){ 414 cleanUrl = cleanUrl.substring(0, index); 415 } 416 if (cleanUrl.startsWith("jar:")){ 417 cleanUrl = cleanUrl.substring(4, cleanUrl.length()); 418 } 419 return new URL (cleanUrl); 420 421 } catch (java.net.MalformedURLException exc){ 422 throw PersistenceUnitLoadingException.exceptionLoadingFromUrl(url, exc); 423 } 424 } 425 426 432 public static String buildClassNameFromEntryString(String classEntryString){ 433 String classNameForLoader = classEntryString; 434 if (classEntryString.endsWith(".class")){ 435 classNameForLoader = classNameForLoader.substring(0, classNameForLoader.length() - 6);; 436 classNameForLoader = classNameForLoader.replace("/", "."); 437 } 438 return classNameForLoader; 439 } 440 441 445 public static Set <String > buildClassSet(PersistenceUnitInfo persistenceUnitInfo){ 446 Set <String > set = new HashSet <String >(); 447 set.addAll(persistenceUnitInfo.getManagedClassNames()); 448 Iterator i = persistenceUnitInfo.getJarFileUrls().iterator(); 449 while (i.hasNext()) { 450 set.addAll(PersistenceUnitProcessor.getClassNamesFromURL((URL )i.next())); 451 } 452 if (!persistenceUnitInfo.excludeUnlistedClasses()){ 453 set.addAll(PersistenceUnitProcessor.getClassNamesFromURL(persistenceUnitInfo.getPersistenceUnitRootUrl())); 454 } 455 return set; 456 } 457 458 464 public static Set <String > buildPersistentClassSet(PersistenceUnitInfo persistenceUnitInfo, ClassLoader loader){ 465 Set <String > set = new HashSet (); 466 467 for (String className : persistenceUnitInfo.getManagedClassNames()) { 468 if (isClassPersistent(className, loader, true)) { 469 set.add(className); 470 } 471 } 472 473 Iterator i = persistenceUnitInfo.getJarFileUrls().iterator(); 474 while (i.hasNext()) { 475 set.addAll(PersistenceUnitProcessor.getPersistentClassNamesFromURL((URL )i.next(), loader)); 476 } 477 if (!persistenceUnitInfo.excludeUnlistedClasses()){ 478 set.addAll(PersistenceUnitProcessor.getPersistentClassNamesFromURL(persistenceUnitInfo.getPersistenceUnitRootUrl(), loader)); 479 } 480 return set; 481 } 482 483 491 protected static List <String > findClassesInDirectory(File directory, int leadingCharactersToRemove){ 492 Vector classes = new Vector (); 493 File [] files = directory.listFiles(); 494 for (File file: files){ 495 if (file.isDirectory()){ 496 classes.addAll(findClassesInDirectory(file, leadingCharactersToRemove)); 497 } 498 if (file.isFile() && file.getName().endsWith(".class")){ 499 String className = file.getPath().substring(leadingCharactersToRemove + 1, file.getPath().length() - 6); 500 className = className.replace("/", "."); 501 className = className.replace("\\", "."); 502 classes.add(className); 503 } 504 } 505 return classes; 506 } 507 508 514 public static Set <URL > findPersistenceArchives(){ 515 ClassLoader threadLoader = Thread.currentThread().getContextClassLoader(); 516 return findPersistenceArchives(threadLoader); 517 } 518 519 520 526 public static Set <URL > findPersistenceArchives(ClassLoader loader){ 527 Set <URL > parURLs = new HashSet <URL >(); 528 try { 529 Enumeration <URL > resources = loader.getResources("META-INF/persistence.xml"); 530 while (resources.hasMoreElements()){ 531 URL url = resources.nextElement(); 532 parURLs.add(url); 533 } 534 } catch (java.io.IOException exc){ 535 throw PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(loader, exc); 536 } 537 return parURLs; 538 } 539 540 546 private static List <String > getClassNamesFromJar(URL url){ 547 InputStream stream = null; 548 List persistentClasses = null; 549 IOException initialException; 550 try { 551 stream = createInputStreamForURL(url); 552 persistentClasses = findClassesInJar(stream); 553 } catch (IOException exc){ 554 throw PersistenceUnitLoadingException.exceptionSearchingForEntities(url, exc); 555 } finally { 556 try{ 557 if (stream != null){ 558 stream.close(); 559 } 560 } catch (IOException exc){}; 561 } 562 return persistentClasses; 563 564 } 565 566 573 private static List findClassesInJar(InputStream stream) throws IOException { 574 JarInputStream jarFile = null; 575 List persistentClasses = new Vector (); 576 try{ 577 jarFile = new JarInputStream (stream); 578 ZipEntry entry = jarFile.getNextEntry(); 579 if (entry == null){ 580 return null; 581 } 582 while (entry != null){ 583 String classNameForLoader = buildClassNameFromEntryString(entry.getName()); 584 if (entry.getName().endsWith(".class")){ 585 persistentClasses.add(classNameForLoader); 586 } 587 entry = jarFile.getNextEntry(); 588 } 589 } finally { 590 try{ 591 if (jarFile != null){ 592 jarFile.close(); 593 } 594 } catch (IOException exc){}; 595 } 596 return persistentClasses; 597 } 598 599 605 private static List <String > getClassNamesFromURL(URL url){ 606 List classNames = null; 607 try { 608 classNames = getClassNamesFromJar(url); 609 if (classNames != null){ 610 return classNames; 611 } 612 } catch (Exception exception){ 613 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, JAR_OPENING_EXCEPTION, url, exception); 614 }; 615 try{ 616 File file = new File (convertURLToURI(url)); 618 if (file.isDirectory()){ 619 return getClassNamesFromDirectory(file); 620 } 621 } catch (Exception exception){ 622 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, DIRECTORY_OPENING_EXCEPTION, url, exception); 623 } 624 return null; 625 } 626 627 633 private static List <String > getClassNamesFromDirectory(File file){ 634 List classList = null; 635 636 if (!file.isDirectory()){ 637 return null; 638 } 639 int initialDirectoryNameLength = file.getPath().length(); 640 classList = findClassesInDirectory(file, initialDirectoryNameLength); 641 return classList; 642 } 643 644 651 public static List <String > getPersistentClassNamesFromDirectory(File file, ClassLoader loader){ 652 List <String > persistentClasses = new Vector <String >(); 653 List <String > classList = getClassNamesFromDirectory(file); 654 for (String className: classList){ 655 if (isClassPersistent(className, loader, false)){ 656 persistentClasses.add(className); 657 } 658 } 659 return persistentClasses; 660 } 661 662 670 public static List getPersistentClassNamesFromURL(URL url, ClassLoader loader){ 671 List classNames = null; 672 try { 673 classNames = getPersistentClassNamesFromJar(url, loader); 674 if (classNames != null){ 675 return classNames; 676 } 677 } catch (Exception exception){ 678 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, JAR_OPENING_EXCEPTION, url, exception); 679 }; 680 try{ 681 File file = new File (convertURLToURI(url)); 683 if (file.isDirectory()){ 684 classNames = getPersistentClassNamesFromDirectory(file, loader); 685 if (classNames != null){ 686 return classNames; 687 } 688 } 689 } catch (Exception exception){ 690 AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, DIRECTORY_OPENING_EXCEPTION, url, exception); 691 }; 692 throw PersistenceUnitLoadingException.couldNotGetClassNamesFromUrl(url); 693 } 694 695 702 public static List <String > getPersistentClassNamesFromJar(URL url, ClassLoader loader){ 703 List <String > classList = getClassNamesFromJar(url); 704 if (classList == null){ 705 return null; 706 } 707 List <String > persistentClasses = new Vector (); 708 for (String className: classList){ 709 if (isClassPersistent(className, loader, false)){ 710 persistentClasses.add(className); 711 } 712 } 713 return persistentClasses; 714 } 715 716 722 public static boolean isClassPersistent(String className, ClassLoader loader, boolean throwExceptionIfNotFound){ 723 Class candidateClass = null; 724 try{ 725 candidateClass = loader.loadClass(className); 726 } catch (ClassNotFoundException exc){ 727 if (throwExceptionIfNotFound){ 728 throw PersistenceUnitLoadingException.exceptionLoadingClassWhileLookingForAnnotations(className, exc); 729 } else { 730 AbstractSessionLog.getLog().log(AbstractSessionLog.WARNING, "persistence_unit_processor_error_loading_class", exc.getClass().getName(), exc.getLocalizedMessage() , className); 731 return false; 732 } 733 } catch (Exception exception){ 734 AbstractSessionLog.getLog().log(AbstractSessionLog.WARNING, "persistence_unit_processor_error_loading_class", exception.getClass().getName(), exception.getLocalizedMessage() , className); 735 return false; 736 } 737 return isClassPersistent(candidateClass); 738 } 739 747 public static boolean isClassPersistent(Class candidateClass){ 748 if (candidateClass.isAnnotationPresent(javax.persistence.Entity.class)) { 749 return true; 750 } 751 return false; 752 } 753 754 760 private static URI convertURLToURI(URL url) { 761 String filePath = url.getFile(); 762 if (filePath.equals("") || filePath == null) { 763 throw PersistenceUnitLoadingException.filePathMissingException(filePath); 764 } 765 766 URI uri = null; 767 try { 768 uri = url.toURI(); 773 } catch (URISyntaxException e) { 774 try{ 775 uri = new URI (url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), null); 777 } catch (URISyntaxException exc){}; 778 if (uri == null){ 779 throw PersistenceUnitLoadingException.exceptionProcessingPersistenceUnit(url, e); 780 } 781 } 782 783 return uri; 784 } 785 786 } 787 | Popular Tags |