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.wsrf.persistence;
36  
37  import java.text.MessageFormat;
38  import java.util.Iterator;
39  import java.util.List;
40  import java.util.Map;
41  import java.util.Vector;
42  
43  import javax.persistence.EntityManager;
44  import javax.persistence.NoResultException;
45  import javax.persistence.NonUniqueResultException;
46  import javax.persistence.Query;
47  import javax.persistence.RollbackException;
48  
49  import org.apache.log4j.Logger;
50  import org.apache.xmlbeans.XmlObject;
51  import org.ogf.graap.wsag.api.Agreement;
52  import org.ogf.graap.wsag.api.AgreementFactory;
53  import org.ogf.graap.wsag.api.AgreementOffer;
54  import org.ogf.graap.wsag.api.Negotiation;
55  import org.ogf.graap.wsag.api.exceptions.AgreementFactoryException;
56  import org.ogf.graap.wsag.api.exceptions.NegotiationFactoryException;
57  import org.ogf.graap.wsag.server.persistence.EmfRegistry;
58  import org.ogf.graap.wsag.server.persistence.PersistedResourceException;
59  import org.ogf.graap.wsag.server.persistence.PersistentAgreement;
60  import org.ogf.graap.wsag.server.persistence.PersistentAgreementFactory;
61  import org.ogf.schemas.graap.wsAgreement.AgreementTemplateType;
62  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationContextType;
63  import org.w3.x2005.x08.addressing.EndpointReferenceType;
64  
65  /**
66   * The {@link WsDatabaseAgreementFactory} encapsulates a {@link PersistentAgreementFactory} and additionally
67   * stores the endpoint reference of the persistent factory. Calls to this factory are delegated to the
68   * {@link PersistentAgreementFactory}.
69   * 
70   * @author thomasw
71   * @author owaeld
72   */
73  public class WsDatabaseAgreementFactory
74      implements WsPersistentAgreementFactory
75  {
76  
77      private static final Logger LOG = Logger.getLogger( WsDatabaseAgreementFactory.class );
78  
79      private final String resourceId;
80  
81      private final EndpointReferenceType factoryEpr;
82  
83      private final PersistentAgreementFactory pFactory;
84  
85      private final List<WsDatabasePersistentAgreement> wsAgreements;
86  
87      /**
88       * Creates a persistent WS agreement factory for a given EPR and implementation.
89       * 
90       * @param factory
91       *            the persistent factory where calls are delegated to
92       * 
93       * @param epr
94       *            the endpoint reference of the persistent factory
95       */
96      public WsDatabaseAgreementFactory( PersistentAgreementFactory factory, EndpointReferenceType epr )
97      {
98          pFactory = factory;
99          this.factoryEpr = epr;
100         this.resourceId = pFactory.getResourceId();
101         this.wsAgreements = new Vector<WsDatabasePersistentAgreement>();
102     }
103 
104     /**
105      * {@inheritDoc}
106      * 
107      * @see org.ogf.graap.wsag.server.persistence.PersistentAgreementFactory#getResourceId()
108      */
109     public String getResourceId()
110     {
111         return resourceId;
112     }
113 
114     /**
115      * {@inheritDoc}
116      * 
117      * @see org.ogf.graap.wsag.server.persistence.PersistentAgreementFactory#getAgreementFactory()
118      * 
119      * @deprecated
120      */
121     @Deprecated
122     public AgreementFactory getAgreementFactory()
123     {
124         return pFactory.getAgreementFactory();
125     }
126 
127     /**
128      * {@inheritDoc}
129      * 
130      * @see org.ogf.graap.wsag.server.persistence.PersistentAgreementFactory#load()
131      */
132     @SuppressWarnings( "unchecked" )
133     public void load() throws Exception
134     {
135         pFactory.load();
136 
137         LOG.debug( "WsSimplePersistentAgreementFactory -> load()" );
138 
139         wsAgreements.clear();
140 
141         EntityManager em = EmfRegistry.getEntityManager();
142         try
143         {
144             LOG.debug( "WsDatabaseAgreementHome -> list(String agreementFactoryId)" );
145 
146             // get a list of all agreement ids with existing EPR
147             Query query = em.createNamedQuery( "AgreementEprContainer.findAllByAgreementFactoryId" );
148             query.setParameter( "agreementFactoryId", resourceId );
149 
150             List<AgreementEprContainer> agreementEprContainers = null;
151             try
152             {
153                 agreementEprContainers = query.getResultList();
154             }
155             catch ( NoResultException ex )
156             {
157                 LOG.error( "Could not find any persisted agreement EPR container." );
158             }
159 
160             if ( LOG.isDebugEnabled() )
161             {
162                 LOG.debug( "Found " + agreementEprContainers.size()
163                     + " AgreementEprContainer for agreementFactoryId '" + resourceId + "'." );
164             }
165 
166             // retrieve the agreement for all found EPRs
167 
168             for ( AgreementEprContainer agreementEprContainer : agreementEprContainers )
169             {
170                 WsDatabasePersistentAgreement wsDatabasePersistentAgreement =
171                     this.findByAgreementId( agreementEprContainer.getAgreementId() );
172                 wsAgreements.add( wsDatabasePersistentAgreement );
173             }
174 
175             if ( LOG.isDebugEnabled() )
176             {
177                 LOG.debug( "Loaded " + wsAgreements.size()
178                     + " WsDatabasePersistentAgreement(s) for agreementFactoryId '" + resourceId + "'." );
179             }
180         }
181         catch ( Exception ex )
182         {
183             LOG.error( "Could not load WS database persistent agreements.", ex );
184         }
185         finally
186         {
187             // close entity manager
188             em.close();
189         }
190 
191     }
192 
193     /**
194      * {@inheritDoc}
195      * 
196      * @see org.ogf.graap.wsag.server.persistence.PersistentAgreementFactory#save()
197      */
198     public void save() throws Exception
199     {
200         pFactory.save();
201     }
202 
203     /**
204      * {@inheritDoc}
205      * 
206      * @see org.ogf.graap.wsag.server.persistence.PersistentAgreementFactory#addAgreement(org.ogf.graap.wsag.api.Agreement,
207      *      org.w3.x2005.x08.addressing.EndpointReferenceType)
208      * 
209      * @deprecated
210      */
211     @Deprecated
212     public void addAgreement( Agreement agreement, EndpointReferenceType epr )
213     {
214         pFactory.addAgreement( agreement, epr );
215     }
216 
217     /**
218      * {@inheritDoc}
219      * 
220      * @see org.ogf.graap.wsag.api.AgreementFactory#getTemplates()
221      */
222     public AgreementTemplateType[] getTemplates()
223     {
224         return pFactory.getTemplates();
225     }
226 
227     /**
228      * {@inheritDoc}
229      * 
230      * @see org.ogf.graap.wsag.api.AgreementFactory#createAgreement(org.ogf.graap.wsag.api.AgreementOffer)
231      */
232     public Agreement createAgreement( AgreementOffer offer ) throws AgreementFactoryException
233     {
234         return pFactory.createAgreement( offer );
235     }
236 
237     /**
238      * {@inheritDoc}
239      * 
240      * @see org.ogf.graap.wsag.api.AgreementFactory#initiateNegotiation(NegotiationContextType, XmlObject[],
241      *      XmlObject[], Map)
242      */
243     public Negotiation
244         initiateNegotiation( NegotiationContextType context, XmlObject[] criticalExtensions,
245                              XmlObject[] nonCriticalExtensions, Map<String, Object> environment )
246             throws NegotiationFactoryException
247     {
248 
249         return pFactory.initiateNegotiation( context, criticalExtensions, nonCriticalExtensions, environment );
250     }
251 
252     /**
253      * Tries to find an agreement for a specified EPR. An agreement can be found, if a corresponding
254      * {@link AgreementEprContainer} instance exists.
255      * 
256      * @param epr
257      *            EPR of the agreement.
258      * 
259      * @return Webservice-version of the persisted agreement.
260      * 
261      * @throws PersistedResourceException
262      *             {@inheritDoc}
263      */
264     public WsDatabasePersistentAgreement find( String epr ) throws PersistedResourceException
265     {
266 
267         LOG.debug( "WsDatabaseAgreementHome -> find(String epr)" );
268 
269         // try to find the agreement EPR
270         EntityManager em = EmfRegistry.getEntityManager();
271         Query query = em.createNamedQuery( "AgreementEprContainer.findByEpr" );
272         query.setParameter( "epr", epr );
273 
274         AgreementEprContainer agreementEprContainer = null;
275         try
276         {
277             agreementEprContainer = (AgreementEprContainer) query.getSingleResult();
278         }
279         catch ( NoResultException ex )
280         {
281             LOG.error( "Could not find an agreement for the EPR '" + epr + "'." );
282             throw new PersistedResourceException( "Could not find an agreement for the EPR '" + epr + "'." );
283         }
284         catch ( NonUniqueResultException ex )
285         {
286             LOG.error( "Found multiple agreements for the EPR '" + epr + "'." );
287             throw new PersistedResourceException( "Found multiple agreements for the EPR '" + epr + "'." );
288         }
289 
290         // build the agreements' EPR
291         EndpointReferenceType theEpr = agreementEprContainer.getEpr();
292 
293         // build the persistent agreement itself
294         PersistentAgreement databasePersistentAgreement =
295             pFactory.find( agreementEprContainer.getAgreementId() );
296         WsDatabasePersistentAgreement wsDatabasePersistentAgreement =
297             new WsDatabasePersistentAgreement( databasePersistentAgreement, theEpr,
298                 agreementEprContainer.getAgreementFactoryId() );
299 
300         // close entity manager
301         em.close();
302 
303         return wsDatabasePersistentAgreement;
304     }
305 
306     /**
307      * Tries to find a agreement for a specified EPR address of an agreement. An agreement can be found, if a
308      * corresponding {@link AgreementEprContainer} instance exists.
309      * 
310      * @param eprAddress
311      *            Address of the EPR of the agreement.
312      * 
313      * @return Webservice-version of the persisted agreement.
314      * 
315      * @throws Exception
316      *             failed to lookup the EPR
317      */
318     public WsDatabasePersistentAgreement findByEprAddress( String eprAddress ) throws Exception
319     {
320 
321         LOG.debug( "WsDatabaseAgreementHome -> findByEprAddress(String eprAddress)" );
322 
323         // try to find the agreement EPR
324         EntityManager em = EmfRegistry.getEntityManager();
325         Query query = em.createNamedQuery( "AgreementEprContainer.findByEprAddress" );
326         query.setParameter( "eprAddress", eprAddress );
327 
328         AgreementEprContainer agreementEprContainer = null;
329         try
330         {
331             agreementEprContainer = (AgreementEprContainer) query.getSingleResult();
332         }
333         catch ( NoResultException ex )
334         {
335             LOG.error( "Could not find an agreement for the EPR address '" + eprAddress + "'." );
336             throw new Exception( "Could not find an agreement for the EPR address '\" + epr + \"'." );
337         }
338         catch ( NonUniqueResultException ex )
339         {
340             LOG.error( "Found multiple agreements for the EPR address '" + eprAddress + "'." );
341             throw new Exception( "Found multiple agreements for the EPR address '" + eprAddress + "'." );
342         }
343 
344         // build the agreements' EPR
345         EndpointReferenceType theEpr = agreementEprContainer.getEpr();
346 
347         // build the persistent agreement itself
348         PersistentAgreement persistentAgreement = pFactory.find( agreementEprContainer.getAgreementId() );
349         WsDatabasePersistentAgreement wsDatabasePersistentAgreement =
350             new WsDatabasePersistentAgreement( persistentAgreement, theEpr,
351                 agreementEprContainer.getAgreementFactoryId() );
352 
353         // close entity manager
354         em.close();
355 
356         return wsDatabasePersistentAgreement;
357     }
358 
359     /**
360      * Creates a list of all webservice-based versions of agreements for one specific agreement factory.
361      * 
362      * @return a list of webservice-based versions of the agreements for the requested agreement factory.
363      */
364     public WsDatabasePersistentAgreement[] list()
365     {
366         return wsAgreements.toArray( new WsDatabasePersistentAgreement[wsAgreements.size()] );
367     }
368 
369     /**
370      * Tries to find a agreement for a specified agreement ID. An agreement can be found, if a corresponding
371      * {@link AgreementEprContainer} instance exists.
372      * 
373      * @param agreementId
374      *            ID of the requested agreement.
375      * 
376      * @return a webservice-version of the persisted agreement.
377      * 
378      * @throws Exception
379      *             failed to look up the specified agreement, i.e. a database error occurred
380      */
381     public WsDatabasePersistentAgreement findByAgreementId( String agreementId ) throws Exception
382     {
383 
384         EndpointReferenceType epr = AgreementEprContainer.findEPRForAgreement( agreementId );
385 
386         // build the persistent agreement itself
387         PersistentAgreement persistentAgreement = pFactory.find( agreementId );
388         WsDatabasePersistentAgreement wsDatabasePersistentAgreement =
389             new WsDatabasePersistentAgreement( persistentAgreement, epr, getResourceId() );
390 
391         return wsDatabasePersistentAgreement;
392     }
393 
394     /**
395      * {@inheritDoc}
396      * 
397      * @see org.ogf.graap.wsag.server.persistence.IAgreementHome#list(java.lang.String)
398      */
399     public PersistentAgreement[] list( String agreementFactoryId ) throws Exception
400     {
401         if ( resourceId.equals( agreementFactoryId ) )
402         {
403             return list();
404         }
405         else
406         {
407             String message = "Agreement Factory ''{0}'' can not list agreements of factory {1}.";
408             LOG.warn( MessageFormat.format( message, new Object[] { resourceId, agreementFactoryId } ) );
409             return new PersistentAgreement[0];
410         }
411     }
412 
413     /**
414      * Removes the factory identified by the given EPR.
415      * 
416      * @param epr
417      *            the EPR that identifies the factory resource
418      * 
419      * @throws PersistedResourceException
420      *             the specified resource was not removed, i.e. it was not found
421      */
422     public void remove( String epr ) throws PersistedResourceException
423     {
424 
425         //
426         // we should either use a method like EPR->equals() or the resource Id for matching EPRs
427         //
428         WsDatabasePersistentAgreement toRemove = null;
429 
430         Iterator<WsDatabasePersistentAgreement> it = wsAgreements.iterator();
431         while ( it.hasNext() )
432         {
433             WsDatabasePersistentAgreement current = it.next();
434             if ( current.getAgreementEPR().xmlText().equals( epr ) )
435             {
436                 toRemove = current;
437                 break;
438             }
439         }
440 
441         if ( toRemove == null )
442         {
443             LOG.error( "Could not find an agreement for the EPR '" + epr + "'." );
444             throw new PersistedResourceException( "Could not find an agreement for the EPR '" + epr + "'." );
445         }
446 
447         // try to find the agreement EPR
448         EntityManager em = EmfRegistry.getEntityManager();
449         try
450         {
451             Query query = em.createNamedQuery( "AgreementEprContainer.findByEpr" );
452             query.setParameter( "epr", epr );
453 
454             // open the transaction
455             em.getTransaction().begin();
456 
457             AgreementEprContainer agreementEprContainer = null;
458             try
459             {
460                 agreementEprContainer = (AgreementEprContainer) query.getSingleResult();
461             }
462             catch ( NoResultException ex )
463             {
464                 LOG.error( "Could not find an agreement for the EPR '" + epr + "' in database." );
465                 em.getTransaction().rollback();
466                 throw new PersistedResourceException( "Could not find an agreement for the EPR '" + epr
467                     + "' in database." );
468             }
469             catch ( NonUniqueResultException ex )
470             {
471                 LOG.error( "Found multiple agreements for the EPR '" + epr + "'." );
472                 em.getTransaction().rollback();
473                 throw new PersistedResourceException( "Found multiple agreements for the EPR '" + epr + "'." );
474             }
475 
476             try
477             {
478                 // remove the EPR for this agreement id and commit
479                 em.remove( agreementEprContainer );
480                 em.getTransaction().commit();
481                 wsAgreements.remove( toRemove );
482             }
483             catch ( RollbackException ex )
484             {
485                 LOG.error( "Could not remove agreement for EPR '" + epr + "'." );
486                 em.getTransaction().rollback();
487                 throw new PersistedResourceException( "Could not remove agreement for EPR '" + epr + "'." );
488             }
489         }
490         finally
491         {
492             // close entity manager
493             em.close();
494         }
495     }
496 
497     /**
498      * {@inheritDoc}
499      * 
500      * @see org.ogf.graap.wsag.wsrf.persistence.WsPersistentAgreementFactory#getAgreementFactoryEPR()
501      */
502     public EndpointReferenceType getAgreementFactoryEPR()
503     {
504         return factoryEpr;
505     }
506 
507 }