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.wsrf.sg.impl;
36  
37  import java.util.HashMap;
38  import java.util.Iterator;
39  import java.util.List;
40  import java.util.Map;
41  import java.util.Vector;
42  
43  import javax.xml.namespace.QName;
44  
45  import org.apache.log4j.Logger;
46  import org.apache.muse.core.Resource;
47  import org.apache.muse.core.serializer.SerializerRegistry;
48  import org.apache.muse.ws.addressing.EndpointReference;
49  import org.apache.muse.ws.addressing.soap.SoapFault;
50  import org.apache.muse.ws.resource.WsResource;
51  import org.apache.muse.ws.resource.sg.MembershipContentRule;
52  import org.apache.muse.ws.resource.sg.ServiceGroupPersistence;
53  import org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup;
54  
55  /**
56   * WSAG4JServiceGroup
57   * 
58   * @author Oliver Waeldrich
59   * 
60   */
61  public class ServiceGroup extends SimpleServiceGroup
62  {
63  
64      private static final Logger LOG = Logger.getLogger( ServiceGroup.class );
65  
66      private Map<EndpointReference, WsResource> entriesByMemberEPR =
67          new HashMap<EndpointReference, WsResource>();
68  
69      private List<WsResource> entryResources = new Vector<WsResource>();
70  
71      /**
72       * For local resources we set the port type of the resource in the MembershipContentRuleContext. After
73       * invocation we remove it from the context.
74       * 
75       * @param memberEPR
76       *            the endpoint reference of the resource to add to the service group
77       * 
78       * @param resource
79       *            the resource to add to the service group
80       * 
81       * @throws SoapFault
82       *             indicates an error while adding the resource
83       * 
84       * @see org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup#resourceAdded(org.apache.muse.ws.addressing.EndpointReference
85       *      , org.apache.muse.core.Resource)
86       */
87      public void resourceAdded( EndpointReference memberEPR, Resource resource ) throws SoapFault
88      {
89          try
90          {
91              QName porttype = resource.getWsdlPortType();
92              if ( porttype != null )
93              {
94                  if ( LOG.isDebugEnabled() )
95                  {
96                      LOG.debug( "Created resource with port type " + porttype
97                          + ". Setting port type for MembershipContentRuleContext." );
98                  }
99  
100                 MembershipContentRuleContext.setPortTypeQName( porttype );
101             }
102             else
103             {
104                 if ( LOG.isDebugEnabled() )
105                 {
106                     LOG.debug( "Could not set port type for MembershipContentRuleContext. WSDL port type is null." );
107                 }
108             }
109 
110             super.resourceAdded( memberEPR, resource );
111         }
112         finally
113         {
114             MembershipContentRuleContext.setPortTypeQName( null );
115         }
116     }
117 
118     /**
119      * Initializes the service group.
120      * 
121      * @throws SoapFault
122      *             indicates an initialization error
123      * 
124      * @see org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup#initialize()
125      */
126     public void initialize() throws SoapFault
127     {
128         super.initialize();
129         SerializerRegistry registry = SerializerRegistry.getInstance();
130         registry.registerSerializer( MembershipContentRule.class, new MembershipContentRuleSerializer() );
131     }
132 
133     /*
134      * (non-Javadoc)
135      * 
136      * @see
137      * org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup#resourceRemoved(org.apache.muse.ws.addressing.
138      * EndpointReference)
139      */
140     @Override
141     public void resourceRemoved( EndpointReference epr ) throws SoapFault
142     {
143         //
144         // if the SG is destroyed, it means we're being told about
145         // our own destruction - don't do anything
146         //
147         if ( hasBeenShutdown() )
148         {
149             getWsResource().getResourceManager().removeListener( this );
150         }
151         else
152         {
153             WsResource entry = getEntry( epr );
154 
155             //
156             // if there was no value in the SG for the EPR, it was
157             // either a wssg:Entry resource (entries do not have
158             // entries themselves, or we'd have infinite recursion)
159             // or a member that was removed by a remote client before
160             // the member was destroyed
161             //
162             if ( entry != null )
163             {
164                 entry.shutdown();
165             }
166         }
167     }
168 
169     //
170     // methods for maintaining the service group
171     //
172 
173     /**
174      * Adds a new entry to the service group.
175      * 
176      * @param memberEPR
177      *            the endpoint reference of the resource to add
178      * 
179      * @param entry
180      *            the resource to add
181      * 
182      * @return the new service group entry
183      */
184     public synchronized WsResource addEntry( EndpointReference memberEPR, WsResource entry )
185     {
186         entriesByMemberEPR.put( memberEPR, entry );
187         entryResources.add( entry );
188         return entry;
189     }
190 
191     /**
192      * Returns all entries in this service group.
193      * 
194      * @return the service group entries
195      */
196     public synchronized WsResource[] getEntry()
197     {
198         WsResource[] asArray = new WsResource[entryResources.size()];
199         return (WsResource[]) entryResources.toArray( asArray );
200     }
201 
202     /**
203      * Retrieves the service group entry identified by the given EPR.
204      * 
205      * @param memberEPR
206      *            the service group entry endpoint reference
207      * 
208      * @return the service group entry
209      */
210     public synchronized WsResource getEntry( EndpointReference memberEPR )
211     {
212         return entriesByMemberEPR.get( memberEPR );
213     }
214 
215     /**
216      * Removes a resource from the service group.
217      * 
218      * @param entry
219      *            the resource to remove
220      */
221     public synchronized void removeEntry( WsResource entry )
222     {
223         if ( entry == null )
224         {
225             throw new NullPointerException( "The entry resource is null." );
226         }
227 
228         //
229         // this is hack-ish - we have to loop through a hash table to find
230         // the right resource. don't have time to go back and refactor the
231         // way we store entries and make this more efficient - besides, it's
232         // more important the additions and lookups be fast
233         //
234         Iterator<EndpointReference> i = entriesByMemberEPR.keySet().iterator();
235         EndpointReference memberEPR = null;
236 
237         while ( i.hasNext() && memberEPR == null )
238         {
239             EndpointReference nextEPR = (EndpointReference) i.next();
240             WsResource nextEntry = (WsResource) entriesByMemberEPR.get( nextEPR );
241 
242             if ( entry == nextEntry )
243             {
244                 memberEPR = nextEPR;
245             }
246         }
247 
248         String message = "The Entry reference was not found in the ServiceGroup, so it could not be removed.";
249         if ( entriesByMemberEPR.remove( memberEPR ) == null )
250         {
251 
252             throw new RuntimeException( message );
253         }
254 
255         if ( !entryResources.remove( entry ) )
256         {
257             throw new RuntimeException( message );
258         }
259 
260         //
261         // if we're using persistence, remove the record of the entry
262         //
263         ServiceGroupPersistence persistence = (ServiceGroupPersistence) getPersistence();
264 
265         try
266         {
267             if ( persistence != null )
268             {
269                 persistence.resourceRemoved( entry.getEndpointReference() );
270             }
271         }
272         catch ( SoapFault fault )
273         {
274             LOG.error( fault );
275         }
276     }
277 
278 }