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.engine;
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.apache.xmlbeans.XmlObject;
44  import org.ogf.graap.wsag.api.Agreement;
45  import org.ogf.graap.wsag.api.AgreementOffer;
46  import org.ogf.graap.wsag.api.Negotiation;
47  import org.ogf.graap.wsag.api.WsagConstants;
48  import org.ogf.graap.wsag.api.exceptions.AgreementFactoryException;
49  import org.ogf.graap.wsag.api.exceptions.NegotiationFactoryException;
50  import org.ogf.graap.wsag.api.logging.LogMessage;
51  import org.ogf.graap.wsag.server.actions.ActionBuilder;
52  import org.ogf.graap.wsag.server.actions.impl.AgreementFactoryAction;
53  import org.ogf.graap.wsag.server.api.impl.AbstractAgreementFactory;
54  import org.ogf.graap.wsag4j.types.configuration.ActionType;
55  import org.ogf.schemas.graap.wsAgreement.AgreementTemplateType;
56  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationContextType;
57  
58  /**
59   * The {@link GenericAgreementFactory} is the default implementation of an agreement factory. It support
60   * configuration of {@link AgreementFactoryAction}'s and automatic offer validation out of the box.
61   * 
62   * @author Oliver Waeldrich
63   * 
64   * @see AgreementFactoryAction
65   */
66  
67  public class GenericAgreementFactory extends AbstractAgreementFactory
68  {
69  
70      private static final Logger LOG = Logger.getLogger( GenericAgreementFactory.class );
71  
72      private boolean initialized = false;
73  
74      private final TemplateRegistry registry = new TemplateRegistry();
75  
76      private TemplateValidator validator;
77  
78      /**
79       * Load the agreement factory actions based on the WSAG4J factory configuration. The factory configuration
80       * is stored in the factory context under the key {@link WsagConstants#WSAG4J_FACTORY_CONFIGURATION}.
81       * 
82       * @return the actions that are configured with the factory
83       * 
84       * @throws Exception
85       *             indicates that an error occurred while loading the actions
86       */
87      protected AgreementFactoryAction[] loadActions() throws Exception
88      {
89          //
90          // Populate the factory context with the factory
91          // configuration, so that action implementations may
92          // look up the factory configuration
93          //
94          getFactoryContext().put( WsagConstants.WSAG4J_FACTORY_CONFIGURATION, getEngineConfiguration() );
95  
96          //
97          // initialize the actions
98          //
99          Vector<AgreementFactoryAction> actions = new Vector<AgreementFactoryAction>();
100 
101         //
102         // for each action configuration section
103         //
104         ActionType[] actionConfig = getEngineConfiguration().getActionArray();
105         for ( int i = 0; i < actionConfig.length; i++ )
106         {
107             actionConfig[i].setName( actionConfig[i].getName() == null ? "<not specified"
108                             : actionConfig[i].getName() );
109 
110             Object[] filler =
111                 new Object[] { new Integer( i + 1 ), new Integer( actionConfig.length ),
112                     actionConfig[i].getName() };
113             String message = MessageFormat.format( "Load action {0} of {1}: {2}", filler );
114             LOG.info( message );
115 
116             try
117             {
118                 AgreementFactoryAction action =
119                     ActionBuilder.getInstance().createAgreementFactoryAction( actionConfig[i],
120                         getFactoryContext() );
121                 actions.add( action );
122             }
123             catch ( Exception ex )
124             {
125                 filler = new Object[] { actionConfig[i].getName(), ex.getMessage() };
126                 message = MessageFormat.format( "Action [{0}] was not loaded. Reason {1}", filler );
127                 LOG.error( message );
128             }
129         }
130 
131         return actions.toArray( new AgreementFactoryAction[actions.size()] );
132     }
133 
134     /**
135      * Initializes a {@link GenericAgreementFactory} instance based on a provided EngineConfiguration. The
136      * initialize method loads the engine configuration, initializes the configured actions, and populates the
137      * action registry.
138      */
139     public synchronized void initialize()
140     {
141         if ( initialized )
142         {
143             return;
144         }
145 
146         try
147         {
148             if ( getEngineConfiguration() == null )
149             {
150                 String message = "Engine configuration must not be null.";
151                 throw new Exception( message );
152             }
153 
154             initializeEngine();
155 
156         }
157         catch ( Exception e )
158         {
159             Object[] filler = new Object[] { e.getMessage() };
160             String message = MessageFormat.format( "Failed to initialize WSAG4J engine. Error: {0}", filler );
161             LOG.error( message );
162         }
163         finally
164         {
165             initialized = true;
166         }
167     }
168 
169     /**
170      * Initializes the WSAG4J engine and instantiates the configrued factory actions.
171      */
172     private void initializeEngine()
173     {
174         AgreementFactoryAction[] actions = new AgreementFactoryAction[0];
175 
176         try
177         {
178             actions = loadActions();
179         }
180         catch ( Exception ex )
181         {
182             actions = new AgreementFactoryAction[0];
183             Object[] filler = new Object[] { ex.getMessage() };
184             String msgErrorLoadActions =
185                 "Error while loading agreement factory actions. No actions were loaded. Reason: {0}";
186             String message = MessageFormat.format( msgErrorLoadActions, filler );
187             LOG.error( message );
188         }
189 
190         for ( int i = 0; i < actions.length; i++ )
191         {
192             try
193             {
194                 LOG.debug( LogMessage.getMessage( "Initialize factory action: {0}", actions[i].getName() ) );
195 
196                 actions[i].initialize();
197 
198                 LOG.debug( LogMessage.getMessage( "Deploy factory action: {0}", actions[i].getName() ) );
199 
200                 registry.add( actions[i] );
201             }
202             catch ( Exception e )
203             {
204                 String message = "Error while initializing action {0}. Action was not loaded. Reason: {1}";
205                 LOG.error( LogMessage.getMessage( message, actions[i].getName(), e.getMessage() ) );
206             }
207         }
208 
209         validator = new TemplateValidator();
210         validator.setConfiguration( getEngineConfiguration().getValidator() );
211     }
212 
213     /**
214      * {@inheritDoc}
215      * 
216      * @see org.ogf.graap.wsag.api.AgreementFactory#createAgreement(org.ogf.graap.wsag.api.AgreementOffer)
217      */
218     public Agreement createAgreement( AgreementOffer offer ) throws AgreementFactoryException
219     {
220         AgreementFactoryAction action = getActionForOffer( offer );
221 
222         if ( action == null )
223         {
224             Object[] filler =
225                 new Object[] { offer.getContext().getTemplateName(), offer.getContext().getTemplateId() };
226             String msgNoActionFound =
227                 "No ICreateAgreementAction found for offer (template name [{0}] : template id [{1}])";
228             String message = MessageFormat.format( msgNoActionFound, filler );
229             throw new AgreementFactoryException( message );
230         }
231 
232         AgreementTemplateType template = getTemplateForOffer( offer );
233 
234         StringBuffer error = new StringBuffer();
235         if ( getValidator().validate( offer, template, error ) )
236         {
237             LOG.info( "Agreement offer successfully validated." );
238 
239             Agreement agreement = action.createAgreement( offer );
240             return agreement;
241         }
242         else
243         {
244             LOG.info( "Agreement offer validation failed." );
245             AgreementFactoryException ex = new AgreementFactoryException( error.toString() );
246             String msgOfferValidationFailed =
247                 "Agreement offer validation failed. The offer is not valid with respect to the template constraints.";
248             throw new AgreementFactoryException( msgOfferValidationFailed, ex );
249 
250         }
251 
252     }
253 
254     /**
255      * {@inheritDoc}
256      */
257     public Negotiation
258         initiateNegotiation( NegotiationContextType context, XmlObject[] criticalExtensions,
259                              XmlObject[] nonCriticalExtensions, Map<String, Object> environment )
260             throws NegotiationFactoryException
261     {
262 
263         Map<String, Object> properties = new HashMap<String, Object>();
264         properties.putAll( environment );
265         properties.put( GenericNegotiation.CRITICAL_EXTENSIONS, criticalExtensions );
266         properties.put( GenericNegotiation.NON_CRITICAL_EXTENSIONS, nonCriticalExtensions );
267 
268         return new GenericNegotiation( this, registry, context, properties );
269     }
270 
271     /**
272      * {@inheritDoc}
273      * 
274      * @see org.ogf.graap.wsag.api.AgreementFactory#getTemplates()
275      */
276     public AgreementTemplateType[] getTemplates()
277     {
278         return registry.getAllTemplates();
279     }
280 
281     private AgreementTemplateType getTemplateForOffer( AgreementOffer offer )
282     {
283         String templateName = offer.getContext().getTemplateName();
284         String templateId = offer.getContext().getTemplateId();
285         return registry.findTemplate( templateName, templateId );
286     }
287 
288     private AgreementFactoryAction getActionForOffer( AgreementOffer offer )
289     {
290         String templateName = offer.getContext().getTemplateName();
291         String templateId = offer.getContext().getTemplateId();
292         return registry.findAction( templateName, templateId );
293     }
294 
295     private synchronized TemplateValidator getValidator()
296     {
297         if ( validator == null )
298         {
299             validator = new TemplateValidator();
300             validator.setConfiguration( getEngineConfiguration().getValidator() );
301         }
302         return validator;
303     }
304 
305     /**
306      * The template registry stores the templates of this factory instance along with the associated
307      * {@link AgreementFactoryAction}.
308      * 
309      * @return the template registry of this factory instance
310      */
311     public TemplateRegistry getTemplateRegistry()
312     {
313         return registry;
314     }
315 
316 }