View Javadoc

1   // SECTION-START[License Header]
2   // <editor-fold defaultstate="collapsed" desc=" Generated License ">
3   /*
4    *   Copyright (c) 2010 The JOMC Project
5    *   Copyright (c) 2005 Christian Schulte <schulte2005@users.sourceforge.net>
6    *   All rights reserved.
7    *
8    *   Redistribution and use in source and binary forms, with or without
9    *   modification, are permitted provided that the following conditions
10   *   are met:
11   *
12   *     o Redistributions of source code must retain the above copyright
13   *       notice, this list of conditions and the following disclaimer.
14   *
15   *     o Redistributions in binary form must reproduce the above copyright
16   *       notice, this list of conditions and the following disclaimer in
17   *       the documentation and/or other materials provided with the
18   *       distribution.
19   *
20   *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
21   *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22   *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23   *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
24   *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25   *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26   *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27   *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29   *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30   *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31   *
32   *   $Id: AbstractJPAContextFactory.java 2242 2010-06-29 07:54:56Z schulte2005 $
33   *
34   */
35  // </editor-fold>
36  // SECTION-END
37  package org.jomc.standalone.ri.naming.support;
38  
39  import java.io.IOException;
40  import java.io.InputStream;
41  import java.net.URL;
42  import java.net.URLClassLoader;
43  import java.util.Enumeration;
44  import java.util.Hashtable;
45  import java.util.LinkedList;
46  import java.util.List;
47  import java.util.Properties;
48  import javax.naming.Context;
49  import javax.naming.NamingException;
50  import javax.persistence.EntityManagerFactory;
51  import javax.persistence.PersistenceException;
52  import javax.persistence.spi.ClassTransformer;
53  import javax.persistence.spi.PersistenceProvider;
54  import javax.persistence.spi.PersistenceUnitInfo;
55  import javax.persistence.spi.PersistenceUnitTransactionType;
56  import javax.sql.DataSource;
57  import javax.xml.parsers.DocumentBuilder;
58  import javax.xml.parsers.DocumentBuilderFactory;
59  import javax.xml.parsers.ParserConfigurationException;
60  import org.w3c.dom.Document;
61  import org.w3c.dom.Element;
62  import org.w3c.dom.NodeList;
63  import org.xml.sax.SAXException;
64  
65  // SECTION-START[Documentation]
66  // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
67  /**
68   * Base JPA context factory.
69   * <p><b>Specifications</b><ul>
70   * <li>{@code 'javax.naming.spi.InitialContextFactory'} {@code (javax.naming.spi.InitialContextFactory)} {@code Multiton}</li>
71   * </ul></p>
72   *
73   * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.0
74   * @version $Id: AbstractJPAContextFactory.java 2242 2010-06-29 07:54:56Z schulte2005 $
75   */
76  // </editor-fold>
77  // SECTION-END
78  // SECTION-START[Annotations]
79  // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
80  @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
81  // </editor-fold>
82  // SECTION-END
83  public abstract class AbstractJPAContextFactory extends AbstractContextFactory
84  {
85      // SECTION-START[InitialContextFactory]
86  
87      public final Context getInitialContext( final Hashtable<?, ?> environment ) throws NamingException
88      {
89          final EntityManagerFactory entityManagerFactory =
90              this.getPersistenceProvider().createContainerEntityManagerFactory(
91              this.getPersistenceUnitInfo(), environment );
92  
93          this.getStandaloneContext().bind( this.getStandaloneEnvironment().getEntityManagerFactoryJndiName(),
94                                            entityManagerFactory );
95  
96          this.getStandaloneContext().bind( this.getStandaloneEnvironment().getEntityManagerJndiName(),
97                                            entityManagerFactory.createEntityManager() );
98  
99          return null;
100     }
101 
102     // SECTION-END
103     // SECTION-START[AbstractJPAContextFactory]
104     private static final String PERSISTENCE_NS = "http://java.sun.com/xml/ns/persistence";
105 
106     private PersistenceUnitInfo persistenceUnitInfo;
107 
108     protected abstract PersistenceProvider getPersistenceProvider();
109 
110     protected PersistenceUnitInfo getPersistenceUnitInfo()
111     {
112         if ( this.persistenceUnitInfo == null )
113         {
114             this.persistenceUnitInfo = new PersistenceUnitInfo()
115             {
116 
117                 private List<ClassTransformer> transformers;
118 
119                 private List<String> managedClasses;
120 
121                 private List<String> mappingFileNames;
122 
123                 private ClassLoader classLoader;
124 
125                 public String getPersistenceUnitName()
126                 {
127                     return "jomc-standalone";
128                 }
129 
130                 public String getPersistenceProviderClassName()
131                 {
132                     return getPersistenceProvider().getClass().getName();
133                 }
134 
135                 public PersistenceUnitTransactionType getTransactionType()
136                 {
137                     return PersistenceUnitTransactionType.JTA;
138                 }
139 
140                 public DataSource getJtaDataSource()
141                 {
142                     try
143                     {
144                         return (DataSource) getStandaloneContext().lookup(
145                             getStandaloneEnvironment().getJtaDataSourceJndiName() );
146 
147                     }
148                     catch ( final NamingException e )
149                     {
150                         throw new PersistenceException( e );
151                     }
152                 }
153 
154                 public DataSource getNonJtaDataSource()
155                 {
156                     return null;
157                 }
158 
159                 public List<String> getMappingFileNames()
160                 {
161                     try
162                     {
163                         if ( this.mappingFileNames == null )
164                         {
165                             this.mappingFileNames = this.getPersistenceUnitElements( "mapping-file" );
166                         }
167 
168                         return this.mappingFileNames;
169                     }
170                     catch ( final SAXException e )
171                     {
172                         throw new PersistenceException( e );
173                     }
174                     catch ( final IOException e )
175                     {
176                         throw new PersistenceException( e );
177                     }
178                     catch ( final ParserConfigurationException e )
179                     {
180                         throw new PersistenceException( e );
181                     }
182                 }
183 
184                 public List<URL> getJarFileUrls()
185                 {
186                     try
187                     {
188                         final List<URL> jarFileUrls = new LinkedList<URL>();
189                         for ( final Enumeration<URL> unitUrls = this.getClassLoader().getResources(
190                             "META-INF/persistence.xml" ); unitUrls.hasMoreElements(); )
191                         {
192                             final URL unitUrl = unitUrls.nextElement();
193                             final String externalForm = unitUrl.toExternalForm();
194                             final String jarUrl = externalForm.substring( 0, externalForm.indexOf( "META-INF" ) );
195                             jarFileUrls.add( new URL( jarUrl ) );
196                         }
197 
198                         return jarFileUrls;
199                     }
200                     catch ( final IOException e )
201                     {
202                         throw new PersistenceException( e );
203                     }
204                 }
205 
206                 public URL getPersistenceUnitRootUrl()
207                 {
208                     return getStandaloneEnvironment().getJpaRootUrl();
209                 }
210 
211                 public List<String> getManagedClassNames()
212                 {
213                     try
214                     {
215                         if ( this.managedClasses == null )
216                         {
217                             this.managedClasses = this.getPersistenceUnitElements( "class" );
218                         }
219 
220                         return this.managedClasses;
221                     }
222                     catch ( final SAXException e )
223                     {
224                         throw new PersistenceException( e );
225                     }
226                     catch ( final IOException e )
227                     {
228                         throw new PersistenceException( e );
229                     }
230                     catch ( final ParserConfigurationException e )
231                     {
232                         throw new PersistenceException( e );
233                     }
234                 }
235 
236                 public boolean excludeUnlistedClasses()
237                 {
238                     return true;
239                 }
240 
241                 public Properties getProperties()
242                 {
243                     return getStandaloneEnvironment().getProperties();
244                 }
245 
246                 public ClassLoader getClassLoader()
247                 {
248                     if ( this.classLoader == null )
249                     {
250                         this.classLoader = new URLClassLoader( new URL[]
251                             {
252                                 getStandaloneEnvironment().getJpaRootUrl()
253                             }, this.getClass().getClassLoader() );
254 
255                     }
256 
257                     return this.classLoader;
258                 }
259 
260                 public void addTransformer( final ClassTransformer transformer )
261                 {
262                     if ( this.transformers == null )
263                     {
264                         this.transformers = new LinkedList<ClassTransformer>();
265                     }
266 
267                     this.transformers.add( transformer );
268                 }
269 
270                 public ClassLoader getNewTempClassLoader()
271                 {
272                     final List<URL> jarFileUrls = this.getJarFileUrls();
273                     jarFileUrls.add( getStandaloneEnvironment().getJpaRootUrl() );
274 
275                     return new URLClassLoader( jarFileUrls.toArray( new URL[ jarFileUrls.size() ] ),
276                                                this.getClass().getClassLoader() );
277 
278                 }
279 
280                 private List<String> getPersistenceUnitElements( final String name )
281                     throws ParserConfigurationException, IOException, SAXException
282                 {
283                     final List<String> elements = new LinkedList<String>();
284                     final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
285                     factory.setNamespaceAware( true );
286                     factory.setValidating( false );
287 
288                     final DocumentBuilder documentBuilder = factory.newDocumentBuilder();
289 
290                     for ( final Enumeration<URL> e = this.getNewTempClassLoader().getResources(
291                         "META-INF/persistence.xml" ); e.hasMoreElements(); )
292                     {
293                         final URL url = e.nextElement();
294                         final InputStream in = url.openStream();
295                         final Document doc = documentBuilder.parse( in );
296                         in.close();
297 
298                         final NodeList persistenceUnits =
299                             doc.getElementsByTagNameNS( PERSISTENCE_NS, "persistence-unit" );
300 
301                         for ( int i = persistenceUnits.getLength() - 1; i >= 0; i-- )
302                         {
303                             final Element persistenceUnit = (Element) persistenceUnits.item( i );
304                             final NodeList nodeList = persistenceUnit.getElementsByTagNameNS( PERSISTENCE_NS, name );
305 
306                             for ( int j = nodeList.getLength() - 1; j >= 0; j-- )
307                             {
308                                 final Element element = (Element) nodeList.item( j );
309                                 elements.add( element.getFirstChild().getNodeValue() );
310                             }
311                         }
312                     }
313 
314                     return elements;
315                 }
316 
317             };
318         }
319 
320         return this.persistenceUnitInfo;
321     }
322 
323     // SECTION-END
324     // SECTION-START[Constructors]
325     // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
326 
327     /** Creates a new {@code AbstractJPAContextFactory} instance. */
328     @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
329     public AbstractJPAContextFactory()
330     {
331         // SECTION-START[Default Constructor]
332         super();
333         // SECTION-END
334     }
335     // </editor-fold>
336     // SECTION-END
337     // SECTION-START[Dependencies]
338     // SECTION-END
339     // SECTION-START[Properties]
340     // SECTION-END
341     // SECTION-START[Messages]
342     // SECTION-END
343 }