You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2010/10/13 13:21:50 UTC

svn commit: r1022069 - in /incubator/aries/trunk/jpa/jpa-container/src: main/java/org/apache/aries/jpa/container/impl/ test/java/org/apache/aries/jpa/container/ test/resources/file23/ test/resources/file23/META-INF/ test/resources/file23/WEB-INF/ test/...

Author: timothyjward
Date: Wed Oct 13 11:21:49 2010
New Revision: 1022069

URL: http://svn.apache.org/viewvc?rev=1022069&view=rev
Log:
ARIES-455 - Process WABs for persistence units

Added:
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/META-INF/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/META-INF/persistence.xml
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/META-INF/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/META-INF/persistence.xml
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/notOnClasspath/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/notOnClasspath/META-INF/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/notOnClasspath/META-INF/persistence.xml
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/onClasspath/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/onClasspath/META-INF/
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/onClasspath/META-INF/persistence.xml
    incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/lib/
Modified:
    incubator/aries/trunk/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceBundleHelper.java
    incubator/aries/trunk/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/PersistenceBundleLifecycleTest.java

Modified: incubator/aries/trunk/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceBundleHelper.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceBundleHelper.java?rev=1022069&r1=1022068&r2=1022069&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceBundleHelper.java (original)
+++ incubator/aries/trunk/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceBundleHelper.java Wed Oct 13 11:21:49 2010
@@ -24,12 +24,14 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 
 import org.apache.aries.jpa.container.parsing.PersistenceDescriptor;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,34 +62,47 @@ public class PersistenceBundleHelper
    * @return
    */
   public static Collection<PersistenceDescriptor> findPersistenceXmlFiles(Bundle bundle)
-  {    
-    String header = (String) bundle.getHeaders().get(PERSISTENCE_UNIT_HEADER);
-    if (header == null) {
-      return Collections.emptySet();
-    }
+  { 
+    Dictionary<String, String> headers = bundle.getHeaders();
+    String metaPersistence = headers.get(PERSISTENCE_UNIT_HEADER);
+    String webContextPath = headers.get(WEB_CONTEXT_PATH_HEADER);
+    
+    Collection<String> locations;
+    
+    if (metaPersistence == null) {
+      if(webContextPath == null) {
+        return Collections.emptySet();
+      } else {
+        // WABs behave a bit differently to normal bundles. We process them even if they don't have a Meta-Persistence
+       
+        if(_logger.isInfoEnabled())
+          _logger.info("The bundle " + bundle.getSymbolicName() + " specifies both the " + 
+                     WEB_CONTEXT_PATH_HEADER + " header, but it does not specify the " + PERSISTENCE_UNIT_HEADER + " header." +
+                     " This bundle will be scanned for persistence descriptors in any locations defined by the JPA specification" +
+                     "that are on the Classpath.");
+        
+        String bundleClassPath = headers.get(Constants.BUNDLE_CLASSPATH);
+        
+        locations = findWABClassPathLocations(bundleClassPath);
+      }
+    } else {
+
+      //Always search the default location, and use a set so we don't search the same
+      //location twice!
+      locations = new HashSet<String>();
+      locations.add(PERSISTENCE_XML);
       
-    // Do not scan WABs
-    if (bundle.getHeaders().get(WEB_CONTEXT_PATH_HEADER) != null) {
-      _logger.warn("The bundle " + bundle.getSymbolicName() + " specifies both the " + 
-                  PERSISTENCE_UNIT_HEADER + " and the " + WEB_CONTEXT_PATH_HEADER + " header. WABs that use JPA " +
-                  "are not supported as part of the OSGi JPA specification. No persistence descriptors will be processed" +
-                  "for this bundle.");
-      return Collections.emptySet();
+      if(!!!metaPersistence.isEmpty()) {
+        //Split apart the header to get the individual entries
+        for (String s : metaPersistence.split(",")) {
+          locations.add(s.trim());
+        }
+      }
     }
-    
+
     //The files we have found
     Collection<PersistenceDescriptor> persistenceXmlFiles = new ArrayList<PersistenceDescriptor>();
     
-    //Always search the default location, and use a set so we don't search the same
-    //location twice!
-    Collection<String> locations = new HashSet<String>();
-    locations.add(PERSISTENCE_XML);
-          
-    //Split apart the header to get the individual entries
-    for (String s : header.split(",")) {
-      locations.add(s.trim());
-    }
-    
     //Find the file and add it to our list
     for (String location : locations) {
       try {
@@ -122,6 +137,45 @@ public class PersistenceBundleHelper
     return persistenceXmlFiles;
   }
 
+  private static Collection<String> findWABClassPathLocations(String bundleClassPath) {
+    
+    Collection<String> locations = new HashSet<String>();
+    
+    if(bundleClassPath == null || bundleClassPath.isEmpty()) {
+      locations.add(PERSISTENCE_XML); 
+    } else {
+      //Remove quoted parameters (that may have , or ; in them)
+      bundleClassPath = bundleClassPath.replaceAll(";[^;,]*?=\\s*\".*?\"", "");
+      //Remove any other parameters
+      bundleClassPath = bundleClassPath.replaceAll(";[^;,]*?=[^;,]*", ",");
+      //Remove any ";" left
+      bundleClassPath = bundleClassPath.replace(';', ',');
+      
+      //Tidy up any duplicate "," we have ended up with
+      bundleClassPath = bundleClassPath.replaceAll(",+", ",");
+      
+      //Finally we have the entries we want
+      String[] entries = bundleClassPath.split(",");
+      
+      for(String entry : entries) {
+        entry = entry.trim();
+        if(entry.isEmpty())
+          continue;
+        else if(".".equals(entry)) {
+          locations.add(PERSISTENCE_XML);
+        } else if(entry.endsWith(".jar")) {
+          locations.add(entry + "!/" + PERSISTENCE_XML);
+        }  else {
+          if(!!!entry.endsWith("/"))
+            entry = entry + "/";
+          
+          locations.add(entry + PERSISTENCE_XML);
+        }
+      }
+    }
+    return locations;
+  }
+
   /**
    * Locate a persistence descriptor file in a bundle
    * based on a String name.

Modified: incubator/aries/trunk/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/PersistenceBundleLifecycleTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/PersistenceBundleLifecycleTest.java?rev=1022069&r1=1022068&r2=1022069&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/PersistenceBundleLifecycleTest.java (original)
+++ incubator/aries/trunk/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/PersistenceBundleLifecycleTest.java Wed Oct 13 11:21:49 2010
@@ -28,10 +28,13 @@ import static org.junit.Assert.assertTru
 
 import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.lang.reflect.Field;
 import java.net.MalformedURLException;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Collections;
 import java.util.Dictionary;
@@ -176,20 +179,51 @@ public class PersistenceBundleLifecycleT
   public void testManager_WABandJPABundle() throws Exception 
   {
     BundleContext ctx = preExistingBundleSetup();
-    setupPersistenceBundle("file23", "");
+    setupPersistenceBundle("file4", "");
     persistenceBundle.getHeaders().put("Web-ContextPath", "/test");
 
     // make sure we don't succeed because of not having a provider
     Hashtable<String,Object> hash1 = new Hashtable<String, Object>();
-    hash1.put("javax.persistence.provider", "use.this.Provider");
+    hash1.put("javax.persistence.provider", "no.such.Provider");
     hash1.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
     ServiceRegistration reg = persistenceBundle.getBundleContext().registerService(new String[] {PersistenceProvider.class.getName()} ,
         pp, hash1 );
-
+    ServiceReference ref = reg.getReference();
+    
     mgr.start(ctx);
     
-    BundleContextMock.assertNoServiceExists(EntityManagerFactory.class.getName());
-    assertNull("We should not have an EntityManagerFactoryManager", getTrackedObject());
+    //Check the persistence.xml was looked for
+    Skeleton.getSkeleton(persistenceBundle).assertCalled(new MethodCall(Bundle.class, "getEntry", "META-INF/persistence.xml"));
+    //Check we didn't use getResource()
+    Skeleton.getSkeleton(persistenceBundle).assertNotCalled(new MethodCall(Bundle.class, "getResource", String.class));
+    
+    testSuccessfulCreationEvent(ref, ctx, 1);
+    testSuccessfulRegistrationEvent(ref, ctx, 1);
+    
+    assertNotNull("We should not have an EntityManagerFactoryManager", getTrackedObject());
+  }
+  
+  @Test
+  public void testManager_WABNoMetaPersistence() throws Exception {
+   
+    
+    BundleContext extenderContext = preExistingBundleSetup();
+    
+    Hashtable<String,String> hash1 = new Hashtable<String, String>();
+    hash1.put("javax.persistence.provider", "no.such.Provider");
+    ServiceRegistration reg = persistenceBundle.getBundleContext().registerService(new String[] {PersistenceProvider.class.getName()} ,
+        pp, hash1 );
+    
+    ServiceReference ref = reg.getReference();
+    setupWABBundle();
+    
+    mgr.start(extenderContext);
+    
+    
+    Skeleton.getSkeleton(persistenceBundle).assertCalledExactNumberOfTimes(new MethodCall(Bundle.class, "getEntry", String.class), 3);
+    
+    testSuccessfulCreationEvent(ref, extenderContext, 3);
+    testSuccessfulRegistrationEvent(ref, extenderContext, 3, "webInfClassesOnClassPath", "jarOne", "jarTwo");
   }
 
   @Test
@@ -1203,6 +1237,66 @@ public class PersistenceBundleLifecycleT
     
   }
 
+  private void setupWABBundle() throws Exception {
+    
+    persistenceBundle.getHeaders().put("Web-ContextPath", "/test2");
+    persistenceBundle.getHeaders().put("Bundle-ClassPath", "WEB-INF/classes/onClasspath, WEB-INF/lib/onClasspath.jar;" +
+    		" WEB-INF/lib/alsoOnClasspath.jar; prop=\"value\"; complexProp:=\"a,b\";complexProp2:= \"c;d\";anotherProp=anotherValue; yetMoreProp=something");
+    
+    Skeleton skel = Skeleton.getSkeleton(persistenceBundle);
+    skel.setReturnValue(new MethodCall(Bundle.class, "getState"), Bundle.ACTIVE);
+
+    URL xml = getClass().getClassLoader().getResource("file23/META-INF/persistence.xml");
+    skel.setReturnValue(new MethodCall(Bundle.class, "getEntry", "META-INF/persistence.xml"), xml);
+    
+    xml = getClass().getClassLoader().getResource("file23/WEB-INF/classes/onClasspath/META-INF/persistence.xml");
+    skel.setReturnValue(new MethodCall(Bundle.class, "getEntry", "WEB-INF/classes/onClasspath/META-INF/persistence.xml"), xml);
+    
+    xml = getClass().getClassLoader().getResource("file23/WEB-INF/classes/notOnClasspath/META-INF/persistence.xml");
+    skel.setReturnValue(new MethodCall(Bundle.class, "getEntry", "WEB-INF/classes/notOnClasspath/META-INF/persistence.xml"), xml);
+    
+    URL root = getClass().getClassLoader().getResource("file23");
+    
+    buildJarFile(skel, root, "WEB-INF/lib/onClasspath.jar", "jarOne");
+    buildJarFile(skel, root, "WEB-INF/lib/alsoOnClasspath.jar", "jarTwo");
+    
+    buildJarFile(skel, root, "WEB-INF/lib/notOnClasspath.jar", "jarNotOnClassPath");
+    
+    skel.setReturnValue(new MethodCall(Bundle.class, "getVersion"), new Version("0.0.0"));
+    
+  }
+
+  private void buildJarFile(Skeleton skel, URL root, String filePath, String pUnitName) throws URISyntaxException,
+      IOException, FileNotFoundException {
+    
+    File f = new File(new File(root.toURI()), filePath);
+    
+    f.getParentFile().mkdirs();
+    
+    JarOutputStream jos = new JarOutputStream(new FileOutputStream(f));
+    
+    jos.putNextEntry(new ZipEntry("META-INF/persistence.xml"));
+    
+    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(jos));
+    writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+    writer.newLine();
+    writer.write("<persistence xmlns=\"http://java.sun.com/xml/ns/persistence\"");
+    writer.newLine();
+    writer.write("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
+    writer.newLine();    
+    writer.write("xsi:schemaLocation=\"http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd\"");
+    writer.newLine();
+    writer.write("version=\"1.0\">");
+    writer.newLine();
+    writer.write("<persistence-unit name=\"" + pUnitName + "\"/>");
+    writer.newLine();
+    writer.write("</persistence>");
+    
+    writer.close();
+    
+    skel.setReturnValue(new MethodCall(Bundle.class, "getEntry", filePath), f.toURI().toURL());
+  }
+  
   private void setupPersistenceBundle(String root, String header) throws MalformedURLException
   {
     persistenceBundle.getHeaders().put("Meta-Persistence", header);

Added: incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/META-INF/persistence.xml?rev=1022069&view=auto
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/META-INF/persistence.xml (added)
+++ incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/META-INF/persistence.xml Wed Oct 13 11:21:49 2010
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+   version="1.0">
+
+  <persistence-unit name="root">
+  	<provider>no.such.Provider</provider>
+  </persistence-unit>  
+  
+</persistence>

Added: incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/META-INF/persistence.xml?rev=1022069&view=auto
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/META-INF/persistence.xml (added)
+++ incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/META-INF/persistence.xml Wed Oct 13 11:21:49 2010
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+   version="1.0">
+
+  <persistence-unit name="webInf">
+  	<provider>no.such.Provider</provider>
+  </persistence-unit>  
+  
+</persistence>

Added: incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/notOnClasspath/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/notOnClasspath/META-INF/persistence.xml?rev=1022069&view=auto
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/notOnClasspath/META-INF/persistence.xml (added)
+++ incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/notOnClasspath/META-INF/persistence.xml Wed Oct 13 11:21:49 2010
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+   version="1.0">
+
+  <persistence-unit name="webInfClassesNotOnClassPath">
+  	<provider>no.such.Provider</provider>
+  </persistence-unit>  
+  
+</persistence>

Added: incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/onClasspath/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/onClasspath/META-INF/persistence.xml?rev=1022069&view=auto
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/onClasspath/META-INF/persistence.xml (added)
+++ incubator/aries/trunk/jpa/jpa-container/src/test/resources/file23/WEB-INF/classes/onClasspath/META-INF/persistence.xml Wed Oct 13 11:21:49 2010
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+   version="1.0">
+
+  <persistence-unit name="webInfClassesOnClassPath">
+  	<provider>no.such.Provider</provider>
+  </persistence-unit>  
+  
+</persistence>