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.server.api.EngineComponent;
44  import org.ogf.graap.wsag.server.persistence.IAgreementFactoryHome;
45  import org.ogf.graap.wsag.server.persistence.PersistedResourceException;
46  import org.ogf.graap.wsag.server.persistence.PersistentAgreementFactory;
47  
48  /**
49   * <p>
50   * Abstract implementation of an agreement factory home. This implementation provides global
51   * configuration-related functions as well as it is responsible to find and load the agreement factory
52   * prototype (based on the configuration).
53   * </p>
54   * 
55   * <p>
56   * All implementations of the {@link IAgreementFactoryHome} interface should extend this abstract
57   * implementation.
58   * </p>
59   * 
60   * @author Oliver Waeldrich
61   * 
62   */
63  public abstract class AbstractWSAG4JPersistence extends EngineComponent
64      implements IAgreementFactoryHome
65  {
66  
67      // //////////////////////////////////////////////////////////////////////////////////
68      // ////// variable definition section ////////
69      // //////////////////////////////////////////////////////////////////////////////////
70  
71      private static final Logger LOG = Logger.getLogger( AbstractWSAG4JPersistence.class );
72  
73      /**
74       * indicates that the persistence layer has changed and a reload is required.
75       */
76      private boolean changed = false;
77  
78      /**
79       * stores the persistent factories of this layer
80       */
81      private final Vector<PersistentAgreementFactory> persistentFactories =
82          new Vector<PersistentAgreementFactory>();
83  
84      /**
85       * stores the known factories by their ids for fast factory lookup
86       */
87      private final Map<String, PersistentAgreementFactory> factoriesById =
88          new HashMap<String, PersistentAgreementFactory>();
89  
90      // //////////////////////////////////////////////////////////////////////////////////
91      // ////// abstract method declaration ////////
92      // //////////////////////////////////////////////////////////////////////////////////
93  
94      /**
95       * Loads the agreement factories for this persistence layer. The load method is invoked during the
96       * initialization process of the persistence layer (see {@link #initialize()}) or during a
97       * {@link #find(String)}, {@link #list()} or {@link #remove(String)} operation
98       * 
99       * 
100      * @return the loaded factories
101      * 
102      * @throws PersistedResourceException
103      *             indicates an error while loading the persistent factories
104      */
105     protected abstract PersistentAgreementFactory[] doLoad() throws PersistedResourceException;
106 
107     /**
108      * Removes a persistent factory from the persistence layer.
109      * 
110      * @param factory
111      *            the factory to remove
112      * 
113      * @return <code>true</code> if the factory was removed, otherwise <code>false</code>
114      * 
115      * @throws PersistedResourceException
116      *             indicates an error while removing the factory
117      */
118     protected abstract boolean doRemove( PersistentAgreementFactory factory )
119         throws PersistedResourceException;
120 
121     // //////////////////////////////////////////////////////////////////////////////////
122     // ////// getter/setter methods ////////
123     // //////////////////////////////////////////////////////////////////////////////////
124 
125     /**
126      * Indicates that the persistence layer has changed and needs to be re-initialized (see
127      * {@link #initialize()}).
128      * 
129      * @return <code>true</code> if the persistence layer needs to be reloaded, otherwise <code>false</code>.
130      */
131     public boolean hasChanged()
132     {
133         return changed;
134     }
135 
136     /**
137      * Sets the flag to indicate that the persistence layer has changed and needs to be re-initialized (see
138      * {@link #initialize()}).
139      * 
140      * @param changed
141      *            <code>true</code> if the persistence layer needs to be reloaded, otherwise
142      *            <code>false</code>
143      */
144     public void setChanged( boolean changed )
145     {
146         this.changed = changed;
147     }
148 
149     // //////////////////////////////////////////////////////////////////////////////////
150     // ////// method implementations ////////
151     // //////////////////////////////////////////////////////////////////////////////////
152 
153     /**
154      * {@inheritDoc}
155      */
156     @Override
157     protected void doInitialize() throws Exception
158     {
159         synchronized ( this )
160         {
161 
162             try
163             {
164                 persistentFactories.clear();
165                 factoriesById.clear();
166 
167                 PersistentAgreementFactory[] factories = doLoad();
168 
169                 for ( int i = 0; i < factories.length; i++ )
170                 {
171                     persistentFactories.add( factories[i] );
172                     factoriesById.put( factories[i].getResourceId(), factories[i] );
173                 }
174 
175                 setChanged( false );
176             }
177             catch ( Exception e )
178             {
179                 String message =
180                     MessageFormat.format(
181                         "Could not load WSAG4J factory instance. Ignoring this instance. Error: {0}",
182                         e.getMessage() );
183                 LOG.error( message, e );
184             }
185 
186         }
187     }
188 
189     /**
190      * Lists the agreement for the factory with the given id.
191      * 
192      * @param agreementFactoryId
193      *            the id of the factory for which the agreements are listed
194      * 
195      * @return the factory with the given id
196      * 
197      * @throws Exception
198      *             indicates an error while looking up the factory at the persistence layer
199      */
200     @Override
201     public PersistentAgreementFactory find( String agreementFactoryId ) throws Exception
202     {
203         if ( hasChanged() )
204         {
205             doInitialize();
206         }
207 
208         PersistentAgreementFactory persistentAgreementFactory = null;
209 
210         // check if the factory is known/available
211         if ( factoriesById.containsKey( agreementFactoryId ) )
212         {
213             persistentAgreementFactory = factoriesById.get( agreementFactoryId );
214         }
215         else
216         {
217             throw new Exception( MessageFormat.format( "No agreement factory with id ''{0}'' found.",
218                 agreementFactoryId ) );
219         }
220 
221         return persistentAgreementFactory;
222     }
223 
224     /**
225      * {@inheritDoc}
226      */
227     @Override
228     public PersistentAgreementFactory[] list() throws Exception
229     {
230 
231         if ( hasChanged() )
232         {
233             doInitialize();
234         }
235 
236         return persistentFactories.toArray( new PersistentAgreementFactory[persistentFactories.size()] );
237     }
238 
239     /**
240      * {@inheritDoc}
241      */
242     @Override
243     public void remove( String factoryId ) throws Exception
244     {
245 
246         if ( hasChanged() )
247         {
248             doInitialize();
249         }
250 
251         if ( factoriesById.containsKey( factoryId ) )
252         {
253             PersistentAgreementFactory factory = factoriesById.get( factoryId );
254 
255             if ( doRemove( factory ) )
256             {
257                 persistentFactories.remove( factory );
258                 factoriesById.remove( factoryId );
259             }
260         }
261     }
262 }