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 }