View Javadoc

1   /* 
2    * Copyright (c) 2007, 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.impl;
36  
37  import java.text.MessageFormat;
38  import java.util.HashMap;
39  import java.util.Map;
40  import java.util.Vector;
41  
42  import org.apache.log4j.Logger;
43  import org.ogf.graap.wsag.api.AgreementFactory;
44  import org.ogf.graap.wsag.api.WsagConstants;
45  import org.ogf.graap.wsag.server.api.IAgreementFactory;
46  import org.ogf.graap.wsag.server.api.impl.AgreementFactoryContext;
47  import org.ogf.graap.wsag.server.api.impl.AgreementFactoryFacade;
48  import org.ogf.graap.wsag.server.persistence.IAgreementFactoryHome;
49  import org.ogf.graap.wsag.server.persistence.PersistedResourceException;
50  import org.ogf.graap.wsag.server.persistence.PersistentAgreementFactory;
51  import org.ogf.graap.wsag4j.types.configuration.WSAG4JEngineConfigurationType;
52  
53  /**
54   * <p>
55   * Abstract implementation of an agreement factory home. This implementation provides global
56   * configuration-related functions as well as it is responsible to find and load the agreement factory
57   * prototype (based on the configuration).
58   * </p>
59   * 
60   * <p>
61   * All implementations of the {@link IAgreementFactoryHome} interface should extend this abstract
62   * implementation.
63   * </p>
64   * 
65   * @author Oliver Waeldrich
66   * 
67   */
68  public abstract class AbstractWSAG4JPersistence
69      implements IAgreementFactoryHome
70  {
71  
72      // //////////////////////////////////////////////////////////////////////////////////
73      // ////// variable definition section ////////
74      // //////////////////////////////////////////////////////////////////////////////////
75  
76      private static final Logger LOG = Logger.getLogger( AbstractWSAG4JPersistence.class );
77  
78      /**
79       * indicates that the persistence layer has changed and a reload is required.
80       */
81      private boolean changed = false;
82  
83      /**
84       * the wsag4j engine configuration
85       */
86      protected WSAG4JEngineConfigurationType wsag4jConfiguration;
87  
88      /**
89       * stores the persistent factories of this layer
90       */
91      private final Vector<PersistentAgreementFactory> persistentFactories =
92          new Vector<PersistentAgreementFactory>();
93  
94      /**
95       * stores the known factories by their ids for fast factory lookup
96       */
97      private final Map<String, PersistentAgreementFactory> factoriesById =
98          new HashMap<String, PersistentAgreementFactory>();
99  
100     // //////////////////////////////////////////////////////////////////////////////////
101     // ////// abstract method declaration ////////
102     // //////////////////////////////////////////////////////////////////////////////////
103 
104     /**
105      * Loads the agreement factories for this persistence layer. The load method is invoked during the
106      * initialization process of the persistence layer (see {@link #initialize()}) or during a
107      * {@link #find(String)}, {@link #list()} or {@link #remove(String)} operation
108      * 
109      * 
110      * @return the loaded factories
111      * 
112      * @throws PersistedResourceException
113      *             indicates an error while loading the persistent factories
114      */
115     protected abstract PersistentAgreementFactory[] doLoad() throws PersistedResourceException;
116 
117     /**
118      * Removes a persistent factory from the persistence layer.
119      * 
120      * @param factory
121      *            the factory to remove
122      * 
123      * @return <code>true</code> if the factory was removed, otherwise <code>false</code>
124      * 
125      * @throws PersistedResourceException
126      *             indicates an error while removing the factory
127      */
128     protected abstract boolean doRemove( PersistentAgreementFactory factory )
129         throws PersistedResourceException;
130 
131     // //////////////////////////////////////////////////////////////////////////////////
132     // ////// getter/setter methods ////////
133     // //////////////////////////////////////////////////////////////////////////////////
134 
135     /**
136      * @return Configuration for this agreement factory home instance.
137      */
138     public WSAG4JEngineConfigurationType getEngineConfiguration()
139     {
140         return wsag4jConfiguration;
141     }
142 
143     /**
144      * @param configuration
145      *            The configuration used to initialize this agreement factory home instance.
146      */
147     public void setEngineConfiguration( WSAG4JEngineConfigurationType configuration )
148     {
149         this.wsag4jConfiguration = configuration;
150     }
151 
152     /**
153      * Indicates that the persistence layer has changed and needs to be re-initialized (see
154      * {@link #initialize()}).
155      * 
156      * @return <code>true</code> if the persistence layer needs to be reloaded, otherwise <code>false</code>.
157      */
158     public boolean hasChanged()
159     {
160         return changed;
161     }
162 
163     /**
164      * Sets the flag to indicate that the persistence layer has changed and needs to be re-initialized (see
165      * {@link #initialize()}).
166      * 
167      * @param changed
168      *            <code>true</code> if the persistence layer needs to be reloaded, otherwise
169      *            <code>false</code>
170      */
171     public void setChanged( boolean changed )
172     {
173         this.changed = changed;
174     }
175 
176     // //////////////////////////////////////////////////////////////////////////////////
177     // ////// method implementations ////////
178     // //////////////////////////////////////////////////////////////////////////////////
179 
180     /**
181      * @param configuration
182      *            Configuration of the wsag4j engine.
183      * 
184      * @return Agreement factory prototype based on the wsag4j configuration.
185      * 
186      * @throws Exception
187      *             failed to initialize the configured factory
188      */
189     protected IAgreementFactory getAgreementFactoryPrototype( WSAG4JEngineConfigurationType configuration )
190         throws Exception
191     {
192         String implementationClass = null;
193 
194         try
195         {
196             implementationClass =
197                 configuration.getFactory().getFactoryImplementation().getImplementationClass();
198 
199             if ( implementationClass == null )
200             {
201                 throw new Exception();
202             }
203         }
204         catch ( Exception ex )
205         {
206             String message =
207                 "Error in WSAG4J configuration: "
208                     + "Could not load agreement factory implementation from configuration file.";
209             throw new Exception( message, ex );
210         }
211 
212         try
213         {
214 
215             Object instance = Class.forName( implementationClass ).newInstance();
216 
217             if ( instance instanceof AgreementFactory )
218             {
219                 AgreementFactory impl = (AgreementFactory) instance;
220 
221                 IAgreementFactory factory = null;
222 
223                 //
224                 // if the implementation is not an instance of
225                 // IWSAG4JAgreementFactory, return a facade for
226                 // the implementation.
227                 //
228                 if ( impl instanceof IAgreementFactory )
229                 {
230                     factory = (IAgreementFactory) impl;
231                 }
232                 else
233                 {
234                     factory = new AgreementFactoryFacade( impl );
235                 }
236 
237                 //
238                 // explicitly initialize the factory context
239                 // and set the engine configuration
240                 //
241                 factory.setFactoryContext( new AgreementFactoryContext( factory ) );
242                 factory.setEngineConfiguration( configuration );
243 
244                 //
245                 // also populate the factory context with the factory
246                 // configuration, so that action implementations may
247                 // look up the factory configuration
248                 //
249                 factory.getFactoryContext().put( WsagConstants.WSAG4J_FACTORY_CONFIGURATION, configuration );
250 
251                 return factory;
252 
253             }
254             else
255             {
256                 Object[] filler = new Object[] { implementationClass, IAgreementFactoryHome.class.getName() };
257                 String msgLoadPersistenceLayerError =
258                     "Error loading WSAG4J persistence layer. Class [{0}] does not implement interface [{1}].";
259                 String message = MessageFormat.format( msgLoadPersistenceLayerError, filler );
260                 throw new Exception( message );
261             }
262 
263         }
264         catch ( ClassNotFoundException e )
265         {
266             String message =
267                 MessageFormat.format(
268                     "Error loading WSAG4J persistence layer. Class [{0}] not found. Error: {1}",
269                     implementationClass, e.getMessage() );
270             throw new Exception( message );
271         }
272         catch ( InstantiationException e )
273         {
274             String message =
275                 MessageFormat.format( "Error loading WSAG4J persistence layer. "
276                     + "Class [{0}] could not be instantiated. Error: {1}", implementationClass,
277                     e.getMessage() );
278             throw new Exception( message );
279         }
280         catch ( IllegalAccessException e )
281         {
282             String message =
283                 MessageFormat.format( "Error loading WSAG4J persistence layer. "
284                     + "Class [{0}] could not be accessed. Error: {1}", implementationClass, e.getMessage() );
285             throw new Exception( message );
286         }
287 
288     }
289 
290     /**
291      * {@inheritDoc}
292      */
293     public void initialize() throws Exception
294     {
295         synchronized ( this )
296         {
297 
298             try
299             {
300                 persistentFactories.clear();
301                 factoriesById.clear();
302 
303                 PersistentAgreementFactory[] factories = doLoad();
304 
305                 for ( int i = 0; i < factories.length; i++ )
306                 {
307                     persistentFactories.add( factories[i] );
308                     factoriesById.put( factories[i].getResourceId(), factories[i] );
309                 }
310 
311                 setChanged( false );
312             }
313             catch ( Exception e )
314             {
315                 Object[] filler = new Object[] { e.getMessage() };
316                 String message =
317                     MessageFormat.format(
318                         "Could not load WSAG4J factory instance. Ignoring this instance. Error: {0}", filler );
319                 LOG.error( message );
320             }
321 
322         }
323     }
324 
325     /**
326      * Lists the agreement for the factory with the given id.
327      * 
328      * @param agreementFactoryId
329      *            the id of the factory for which the agreements are listed
330      * 
331      * @return the factory with the given id
332      * 
333      * @throws Exception
334      *             indicates an error while looking up the factory at the persistence layer
335      */
336     public PersistentAgreementFactory find( String agreementFactoryId ) throws Exception
337     {
338         if ( hasChanged() )
339         {
340             initialize();
341         }
342 
343         PersistentAgreementFactory persistentAgreementFactory = null;
344 
345         // check if the factory is known/available
346         if ( factoriesById.containsKey( agreementFactoryId ) )
347         {
348             persistentAgreementFactory = factoriesById.get( agreementFactoryId );
349         }
350         else
351         {
352             throw new Exception( MessageFormat.format( "No agreement factory with id ''{0}'' found.",
353                 agreementFactoryId ) );
354         }
355 
356         return persistentAgreementFactory;
357     }
358 
359     /**
360      * {@inheritDoc}
361      */
362     public PersistentAgreementFactory[] list() throws Exception
363     {
364 
365         if ( hasChanged() )
366         {
367             initialize();
368         }
369 
370         return persistentFactories.toArray( new PersistentAgreementFactory[persistentFactories.size()] );
371     }
372 
373     /**
374      * {@inheritDoc}
375      */
376     public void remove( String factoryId ) throws Exception
377     {
378 
379         if ( hasChanged() )
380         {
381             initialize();
382         }
383 
384         if ( factoriesById.containsKey( factoryId ) )
385         {
386             PersistentAgreementFactory factory = factoriesById.get( factoryId );
387 
388             if ( doRemove( factory ) )
389             {
390                 persistentFactories.remove( factory );
391                 factoriesById.remove( factoryId );
392             }
393         }
394     }
395 }