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.api.types;
36  
37  import java.util.HashMap;
38  import java.util.Map;
39  
40  import org.apache.xmlbeans.XmlObject;
41  import org.ogf.graap.wsag.api.Agreement;
42  import org.ogf.graap.wsag.api.AgreementOffer;
43  import org.ogf.schemas.graap.wsAgreement.AgreementContextType;
44  import org.ogf.schemas.graap.wsAgreement.AgreementPropertiesDocument;
45  import org.ogf.schemas.graap.wsAgreement.AgreementPropertiesType;
46  import org.ogf.schemas.graap.wsAgreement.AgreementRoleType;
47  import org.ogf.schemas.graap.wsAgreement.AgreementStateDefinition;
48  import org.ogf.schemas.graap.wsAgreement.AgreementStateType;
49  import org.ogf.schemas.graap.wsAgreement.GuaranteeTermStateDefinition;
50  import org.ogf.schemas.graap.wsAgreement.GuaranteeTermStateType;
51  import org.ogf.schemas.graap.wsAgreement.GuaranteeTermType;
52  import org.ogf.schemas.graap.wsAgreement.ServiceDescriptionTermType;
53  import org.ogf.schemas.graap.wsAgreement.ServiceTermStateDefinition;
54  import org.ogf.schemas.graap.wsAgreement.ServiceTermStateType;
55  import org.ogf.schemas.graap.wsAgreement.TemplateDocument;
56  import org.ogf.schemas.graap.wsAgreement.TermTreeType;
57  import org.w3c.dom.Text;
58  
59  /**
60   * Abstract implementation of an agreement. This class implements the required methods to access and store the
61   * properties of an agreement. Additionally, when an agreement is created based on an offer, the corresponding
62   * states are created for each service term and each guarantee term specified in the offer.
63   * 
64   * @TODO a future implementation of agreement type will use a handler mechanism to implement the agreement
65   *       termination strategy. For that reason, this class will not be abstract anymore and subclassing of
66   *       {@link AbstractAgreementType} will not be required anymore. This will make the framework more robust
67   *       for user implementations.
68   * @TODO Implement Observer pattern to allow registered objects to get notified if the abstract agreement is
69   *       updated.
70   * @author Oliver Waeldrich
71   */
72  public abstract class AbstractAgreementType extends WSAGXmlType implements Agreement
73  {
74  
75      /**
76       * The internal XML representation of the agreement instance.
77       */
78      protected AgreementPropertiesType agreementProperties;
79  
80      /**
81       * Default XPath expression for selecting all service description terms in an agreement.
82       */
83      protected static final String DEFAULT_SDT_XPATH =
84          "declare namespace wsag='http://schemas.ggf.org/graap/2007/03/ws-agreement';"
85              + "$this/wsag:Terms/wsag:All//wsag:ServiceDescriptionTerm";
86  
87      /**
88       * Default XPath expression for selecting all guarantee terms in an agreement.
89       */
90      protected static final String DEFAULT_GUARANTEE_TERM_XPATH =
91          "declare namespace wsag='http://schemas.ggf.org/graap/2007/03/ws-agreement';"
92              + "$this/wsag:Terms/wsag:All//wsag:GuaranteeTerm";
93  
94      /**
95       * Persisted Execution Context of the agreement instance.
96       */
97      private Map<String, XmlObject> persistedExecutionContext = new HashMap<String, XmlObject>();
98      
99      /**
100      * Transcient (Non-Persisted) Execution Context of the agreement instance.
101      */
102     private Map<String, Object> transcientExecutionContext = new HashMap<String, Object>();
103 
104     /**
105      * Creates an agreement based on an offer. The service term states and guarantee term states are
106      * automatically created. For each service description term and each guarantee term in the offer an
107      * appropriate state is created. for the term selection the according {@link #DEFAULT_SDT_XPATH} and
108      * {@link #DEFAULT_GUARANTEE_TERM_XPATH}XPath expression are used.
109      * 
110      * @param offer
111      *            the offer to create the agreement for
112      */
113     public AbstractAgreementType( AgreementOffer offer )
114     {
115         super();
116         initialize( offer );
117     }
118 
119     /**
120      * Creates a new agreement instance. The provided agreement properties document is used for this instance.
121      * 
122      * @param agreementPropertiesType
123      *            the agreement properties document
124      */
125     public AbstractAgreementType( AgreementPropertiesType agreementPropertiesType )
126     {
127         super();
128         this.agreementProperties = agreementPropertiesType;
129     }
130 
131     /**
132      * Default constructor. Initializes a minimal resource properties document for this instance with minimal
133      * default values.
134      */
135     public AbstractAgreementType()
136     {
137         super();
138 
139         TemplateDocument templateDoc = TemplateDocument.Factory.newInstance();
140 
141         templateDoc.addNewTemplate();
142 
143         templateDoc.getTemplate().setAgreementId( "ID" );
144         templateDoc.getTemplate().addNewContext().setServiceProvider( AgreementRoleType.AGREEMENT_RESPONDER );
145 
146         TermTreeType terms = templateDoc.getTemplate().addNewTerms();
147 
148         // will be fixed in MUSE version 2.2.0
149         // Muse Hack Issue 159 - Muse does not honor empty elements and therefore fails
150         // if an element contains no children and the children are optional (minOccours = 0)
151         // therefore we simply include a white space as text content
152         // should be removed as soon as fixed
153 
154         Text text = terms.getDomNode().getOwnerDocument().createTextNode( " " );
155         terms.getDomNode().appendChild( text );
156 
157         initialize( new AgreementOfferType( templateDoc.getTemplate() ) );
158     }
159 
160     /**
161      * Validates the resource properties document of this instance.
162      * 
163      * @return true if the resource properties document is valid, otherwise false.
164      */
165     public boolean validate()
166     {
167         return validate( agreementProperties );
168     }
169 
170     /**
171      * Initializes an agreement type with the standard selection strategy for service description term states
172      * and guarantee term states.
173      * 
174      * @param offer
175      *            The agreement offer that is used for the agreement initialization process.
176      */
177     protected void initialize( AgreementOffer offer )
178     {
179         initialize( offer, DEFAULT_SDT_XPATH, DEFAULT_GUARANTEE_TERM_XPATH );
180     }
181 
182     /**
183      * Initializes an agreement type with the custom selection strategy for service description term states
184      * and guarantee term states.
185      * 
186      * @param offer
187      *            The agreement offer that is used for the agreement initialization process.
188      * @param sdtXPath
189      *            Custom expression for selecting service terms from the agreement offer.
190      * @param guaranteeTermXPath
191      *            Custom expression for selecting guarantee terms from the agreement offer.
192      */
193     protected void initialize( AgreementOffer offer, String sdtXPath, String guaranteeTermXPath )
194     {
195         //
196         // agreementProperties should be an XML element node, not a document fragment
197         //
198         agreementProperties = AgreementPropertiesDocument.Factory.newInstance().addNewAgreementProperties();
199 
200         agreementProperties.setAgreementId( offer.getAgreementId() );
201         agreementProperties.addNewContext().set( offer.getContext() );
202         agreementProperties.addNewTerms().set( offer.getTerms() );
203 
204         agreementProperties.addNewAgreementState().setState( AgreementStateDefinition.OBSERVED );
205 
206         //
207         // Create a new (empty) SDT state document for each SDT in the offer.
208         // There is no extra (monitoring) data associated with this SDT.
209         //
210         XmlObject[] sdtArray = offer.getXMLObject().selectPath( sdtXPath );
211         for ( int i = 0; i < sdtArray.length; i++ )
212         {
213             ServiceDescriptionTermType sdt = (ServiceDescriptionTermType) sdtArray[i];
214             ServiceTermStateType sdtState = agreementProperties.addNewServiceTermState();
215 
216             sdtState.setTermName( sdt.getName() );
217             sdtState.setState( ServiceTermStateDefinition.NOT_READY );
218         }
219 
220         //
221         // Create a new guarantee term state document for each guarantee term in the offer.
222         // The default state is not determined.
223         //
224         XmlObject[] guaranteeArray = offer.getXMLObject().selectPath( guaranteeTermXPath );
225         for ( int i = 0; i < guaranteeArray.length; i++ )
226         {
227             GuaranteeTermType guarantee = (GuaranteeTermType) guaranteeArray[i];
228             GuaranteeTermStateType guaranteeState = agreementProperties.addNewGuaranteeTermState();
229 
230             guaranteeState.setTermName( guarantee.getName() );
231             guaranteeState.setState( GuaranteeTermStateDefinition.NOT_DETERMINED );
232         }
233     }
234 
235     /**
236      * This method allows an agreement instance to get notified after reload. An invocation of the
237      * {@link #notifyReload(Map)} method sets the execution context (see {@link #getExecutionContext()}) of
238      * the agreement and invokes the {@link #notifyReinitialized(Map)} method of this agreement instance.
239      * 
240      * @param executionCtx
241      *            the current execution context
242      */
243     public final void notifyReload( Map<String, XmlObject> executionCtx )
244     {
245         persistedExecutionContext = executionCtx;
246         notifyReinitialized( persistedExecutionContext );
247     }
248 
249     /**
250      * Reload hook. Implementations can overwrite this method in order to implement custom functionality on
251      * agreement reload.
252      * 
253      * @param persistedExecutionCtx
254      *            persisted execution properties of the agreement instance
255      *            <p>
256      *            Since 1.0.0-m4
257      *            </p>
258      */
259     protected void notifyReinitialized( Map<String, XmlObject> persistedExecutionCtx )
260     {
261     }
262 
263     /**
264      * {@inheritDoc}
265      */
266     public String getAgreementId()
267     {
268         return agreementProperties.getAgreementId();
269     }
270 
271     /**
272      * {@inheritDoc}
273      */
274     public AgreementContextType getContext()
275     {
276         return agreementProperties.getContext();
277     }
278 
279     /**
280      * {@inheritDoc}
281      */
282     public String getName()
283     {
284         return agreementProperties.getName();
285     }
286 
287     /**
288      * {@inheritDoc}
289      */
290     public TermTreeType getTerms()
291     {
292         return agreementProperties.getTerms();
293     }
294 
295     /**
296      * Sets the ID of the agreement.
297      * 
298      * @param agreementId
299      *            the agreement id to set
300      */
301     public void setAgreementId( String agreementId )
302     {
303         agreementProperties.setAgreementId( agreementId );
304         setChanged();
305     }
306 
307     /**
308      * Sets the context of the agreement.
309      * 
310      * @param context
311      *            the agreement context to set
312      */
313     public void setContext( AgreementContextType context )
314     {
315         agreementProperties.setContext( context );
316         setChanged();
317     }
318 
319     /**
320      * Sets the name of the agreement.
321      * 
322      * @param name
323      *            the agreement name to set
324      */
325     public void setName( String name )
326     {
327         agreementProperties.setName( name );
328         setChanged();
329     }
330 
331     /**
332      * Sets the terms of the agreement.
333      * 
334      * @param terms
335      *            the agreement terms to set
336      */
337     public void setTerms( TermTreeType terms )
338     {
339         agreementProperties.setTerms( terms );
340         setChanged();
341     }
342 
343     /**
344      * {@inheritDoc}
345      */
346     public AgreementStateType getState()
347     {
348         return agreementProperties.getAgreementState();
349     }
350 
351     /**
352      * {@inheritDoc}
353      */
354     public GuaranteeTermStateType[] getGuaranteeTermStates()
355     {
356         GuaranteeTermStateType[] guarateeStates = agreementProperties.getGuaranteeTermStateArray();
357 
358         if ( guarateeStates == null )
359         {
360             return new GuaranteeTermStateType[0];
361         }
362 
363         return guarateeStates;
364     }
365 
366     /**
367      * {@inheritDoc}
368      */
369     public ServiceTermStateType[] getServiceTermStates()
370     {
371         ServiceTermStateType[] serviceStates = agreementProperties.getServiceTermStateArray();
372 
373         if ( serviceStates == null )
374         {
375             return new ServiceTermStateType[0];
376         }
377 
378         return serviceStates;
379     }
380 
381     /**
382      * Sets the state of the agreement.
383      * 
384      * @param agreementState
385      *            the agreement state to set
386      */
387     public void setState( AgreementStateType agreementState )
388     {
389         agreementProperties.setAgreementState( agreementState );
390         setChanged();
391     }
392 
393     /**
394      * Sets the guarantee term states of the agreement.
395      * 
396      * @param guaranteeTermStateList
397      *            the guarantee term states to set
398      */
399     public void setGuaranteeTermStates( GuaranteeTermStateType[] guaranteeTermStateList )
400     {
401         agreementProperties.setGuaranteeTermStateArray( guaranteeTermStateList );
402         setChanged();
403     }
404 
405     /**
406      * Sets the service term states of the agreement.
407      * 
408      * @param serviceTermStateList
409      *            the service term states to set
410      */
411     public void setServiceTermStates( ServiceTermStateType[] serviceTermStateList )
412     {
413         agreementProperties.setServiceTermStateArray( serviceTermStateList );
414         setChanged();
415     }
416 
417     /**
418      * Returns the agreement properties as {@link XmlObject}.
419      * 
420      * @return an XML representation of the agreement properties document
421      */
422     public XmlObject getXMLObject()
423     {
424         return agreementProperties;
425     }
426 
427     /**
428      * Sets the properties for this agreement explicitly.
429      * 
430      * @param properties
431      *            the agreement properties to set
432      */
433     public void setXmlObject( AgreementPropertiesType properties )
434     {
435         agreementProperties = properties;
436         setChanged();
437     }
438 
439     /**
440      * {@inheritDoc}
441      */
442     public AbstractAgreementType getAgreementInstance()
443     {
444         return this;
445     }
446 
447     /**
448      * Returns the persisted execution context for this agreement.
449      * 
450      * @return the agreement persisted execution context
451      */
452     public Map<String, XmlObject> getExecutionContext()
453     {
454         return persistedExecutionContext;
455     }
456     
457     /**
458      * Returns the transient execution context for this agreement.
459      * 
460      * @return the agreement transient execution context
461      */
462     public Map<String, Object> getTransientExecutionContext()
463     {
464         return transcientExecutionContext;
465     }
466     
467     
468 }