View Javadoc

1   /* 
2    * Copyright (c) 2005-2011, Fraunhofer-Gesellschaft
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are
7    * met:
8    * 
9    * (1) Redistributions of source code must retain the above copyright
10   *     notice, this list of conditions and the disclaimer at the end.
11   *     Redistributions in binary form must reproduce the above copyright
12   *     notice, this list of conditions and the following disclaimer in
13   *     the documentation and/or other materials provided with the
14   *     distribution.
15   * 
16   * (2) Neither the name of Fraunhofer nor the names of its
17   *     contributors may be used to endorse or promote products derived
18   *     from this software without specific prior written permission.
19   * 
20   * DISCLAIMER
21   * 
22   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   *  
34   */
35  package org.ogf.graap.wsag.server.persistence;
36  
37  import java.text.MessageFormat;
38  
39  import javax.persistence.EntityManager;
40  import javax.persistence.EntityManagerFactory;
41  import javax.persistence.Persistence;
42  
43  import org.apache.log4j.Logger;
44  import org.ogf.graap.wsag.api.logging.LogMessage;
45  
46  /**
47   * @author T.Weuffel
48   */
49  public class EmfRegistry
50  {
51  
52      private static final Logger LOG = Logger.getLogger( EmfRegistry.class );
53  
54      /**
55       * System property to set the WSAG4J database location.
56       */
57      public static final String WSAG4J_DATAPATH = "org.wsag4j.persistence.datapath";
58  
59      /**
60       * Default location of the wsag4j hsql database.
61       */
62      public static final String WSAG4J_DATAPATH_DEFAULT = System.getProperty( "java.io.tmpdir" )
63          + "/wsag-data";
64  
65      /**
66       * Persistence mode memory
67       * 
68       * <p>
69       * This mode starts wsag4j with an in-memory database. It supports persistence for the wsag4j-server and
70       * wsag4j-webservice modules. Since an in-memory db is used agreements will not be stored on disk. After
71       * restarting the wsag4j engine all agreements disappear. This mode is usually used for unit testing.
72       * </p>
73       * 
74       */
75      public static final String PERSISTENCE_MODE_MEM = "MEM";
76  
77      /**
78       * Persistence unit name for memory mode (see wsag4j-server-resources /META-INF/persistence.xml)
79       */
80      public static final String PERSISTENCE_MODE_MEM_PU_NAME = "wsag4j_mem";
81  
82      /**
83       * Persistence mode memory for server tests
84       * 
85       * <p>
86       * This mode starts wsag4j with an in-memory database. It supports persistence for the wsag4j-server
87       * module only. Since an in-memory db is used agreements will not be stored on disk. After restarting the
88       * wsag4j engine all agreements disappear. This mode is usually used for unit testing.
89       * </p>
90       */
91      public static final String PERSISTENCE_MODE_MEM_SERVER = "MEM_SERVER";
92  
93      /**
94       * Persistence unit name for memory mode for server tests (see wsag4j-server-resources
95       * /META-INF/persistence.xml)
96       */
97      public static final String PERSISTENCE_MODE_MEM_SERVER_PU_NAME = "wsag4j_mem_server";
98  
99      /**
100      * Persistence mode file
101      * 
102      * <p>
103      * This mode starts wsag4j with an file database. It supports persistence for the wsag4j-server and
104      * wsag4j-webservice modules. Since an file db is used agreements will be stored on disk. After restarting
105      * the wsag4j engine all agreements are reloaded. This mode is usually used for productive mode.
106      * </p>
107      * 
108      * <p>
109      * <b>Important:</b> Make sure that the <code>org.wsag4j.persistence.datapath</code> system property is
110      * set to the correct location of the hsqldb database directory. Otherwise the database will be stored in
111      * {java.io.tmpdir}/wsag-data
112      * </p>
113      */
114     public static final String PERSISTENCE_MODE_FILE = "FILE";
115 
116     /**
117      * Persistence unit name for file mode (see wsag4j-server-resources /META-INF/persistence.xml)
118      */
119     public static final String PERSISTENCE_MODE_FILE_PU_NAME = "wsag4j_file";
120 
121     private static EntityManagerFactory emf;
122 
123     private static String persistenceMode = PERSISTENCE_MODE_FILE;
124 
125     /**
126      * Sets the persistence mode.
127      * 
128      * @param persistenceMode
129      *            the persistence mode to set
130      */
131     public static void setPersistenceMode( String persistenceMode )
132     {
133         EmfRegistry.persistenceMode = persistenceMode;
134 
135         LOG.debug( LogMessage.getMessage( "Set wsag4j persistence mode to: {0}", persistenceMode ) );
136     }
137 
138     /**
139      * Returns an entity manager factory, if no instance exists a new is created.
140      * 
141      * @return the entity manager factory
142      */
143     private static synchronized EntityManagerFactory getEntityManagerFactory()
144     {
145 
146         // if no EMF exists, create a new one
147         if ( emf == null )
148         {
149             createEmf();
150 
151             LOG.info( "No EMF instance exists. Created new instance." );
152 
153             return emf;
154         }
155 
156         // if EMF was closed, create a new one
157         if ( !emf.isOpen() )
158         {
159             createEmf();
160 
161             if ( LOG.isInfoEnabled() )
162             {
163                 LOG.info( "Former EMF instance is/was closed. Created a new instance." );
164             }
165         }
166 
167         return emf;
168     }
169 
170     private static void createEmf()
171     {
172         //
173         // Fixes shutdown errors in Tomcat for HSQL DB
174         //
175 
176         // System.setProperty("org.quartz.scheduler.makeSchedulerThreadDaemon", "true");
177         // System.setProperty("org.quartz.threadPool.makeThreadsDaemons", "true");
178 
179         //
180         // initialize DB
181         //
182         String configuredPersistenceMode = System.getProperty( "wsag4j.persistence.mode" );
183         if ( configuredPersistenceMode != null )
184         {
185             persistenceMode = configuredPersistenceMode;
186 
187             if ( LOG.isInfoEnabled() )
188             {
189                 LOG.info( LogMessage.getMessage(
190                     "Set wsag4j persistence mode to: {0} (by System.getProperty)", persistenceMode ) );
191             }
192         }
193 
194         if ( persistenceMode.equals( PERSISTENCE_MODE_MEM ) )
195         {
196             emf = Persistence.createEntityManagerFactory( PERSISTENCE_MODE_MEM_PU_NAME );
197         }
198         if ( persistenceMode.equals( PERSISTENCE_MODE_MEM_SERVER ) )
199         {
200             emf = Persistence.createEntityManagerFactory( PERSISTENCE_MODE_MEM_SERVER_PU_NAME );
201         }
202         else if ( persistenceMode.equals( PERSISTENCE_MODE_FILE ) )
203         {
204             // check WSAG4J_DATAPATH configuration
205             String configuredDataPath =
206                 System.getProperties().getProperty( WSAG4J_DATAPATH, WSAG4J_DATAPATH_DEFAULT );
207             if ( !"".equals( configuredDataPath ) )
208             {
209 
210                 if ( !( configuredDataPath.endsWith( "/" ) || configuredDataPath.endsWith( "\\" ) ) )
211                 {
212                     configuredDataPath += "/";
213                 }
214 
215                 LOG.debug( LogMessage.getMessage( "WSAG4J persistence data path configuration: {0}",
216                     configuredDataPath ) );
217             }
218             else
219             {
220                 String message =
221                     MessageFormat.format(
222                         "No wsag4j persistence data path configured. Use default location {0}",
223                         WSAG4J_DATAPATH_DEFAULT );
224                 LOG.warn( message );
225             }
226 
227             //
228             // set data path in system properties so that HSQLDB can write the database to the
229             // configured/default location
230             //
231             System.setProperty( WSAG4J_DATAPATH, configuredDataPath );
232 
233             //
234             // try to create the file-based entity manager factory
235             //
236             emf = Persistence.createEntityManagerFactory( PERSISTENCE_MODE_FILE_PU_NAME );
237         }
238         else
239         {
240             LOG.error( "No persistence operation mode configured." );
241         }
242     }
243 
244     /**
245      * Creates a new entity manager.
246      * 
247      * @return the new entity manager
248      */
249     public static EntityManager getEntityManager()
250     {
251         return EmfRegistry.getEntityManagerFactory().createEntityManager();
252     }
253 
254     /**
255      * Returns the operation mode info message.
256      * 
257      * @return info message
258      */
259     public static String printInfo()
260     {
261         return MessageFormat.format(
262             "EmfRegistry [EmfRegistry.persistenceMode: ''{0}'', WSAG4J_DATAPATH: ''{1}'']",
263             EmfRegistry.persistenceMode, WSAG4J_DATAPATH );
264     }
265 
266     /**
267      * Closes the entity manager factory and all entity managers.
268      */
269     public static synchronized void finalizeEmfRegistry()
270     {
271         if ( emf != null )
272         {
273             synchronized ( emf )
274             {
275                 if ( emf.isOpen() )
276                 {
277                     emf.close();
278                 }
279                 emf = null;
280             }
281         }
282     }
283 }