View Javadoc

1   /*
2    * $Id: DefaultMuleSession.java 18952 2010-08-11 16:07:25Z rossmason $
3    * -------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.session;
12  
13  import org.mule.api.MuleContext;
14  import org.mule.api.MuleException;
15  import org.mule.api.MuleMessage;
16  import org.mule.api.MuleSession;
17  import org.mule.api.construct.FlowConstruct;
18  import org.mule.api.security.SecurityContext;
19  import org.mule.api.transport.SessionHandler;
20  import org.mule.config.i18n.CoreMessages;
21  import org.mule.util.CaseInsensitiveHashMap;
22  import org.mule.util.UUID;
23  import org.mule.util.store.DeserializationPostInitialisable;
24  
25  import java.io.IOException;
26  import java.io.ObjectInputStream;
27  import java.io.ObjectOutputStream;
28  import java.io.OptionalDataException;
29  import java.util.Collections;
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.Map;
33  import java.util.Set;
34  
35  import org.apache.commons.collections.map.CaseInsensitiveMap;
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  /**
40   * <code>DefaultMuleSession</code> manages the interaction and distribution of events for
41   * Mule Services.
42   */
43  
44  public final class DefaultMuleSession implements MuleSession, DeserializationPostInitialisable
45  {
46      /**
47       * Serial version
48       */
49      private static final long serialVersionUID = 3380926585676521866L;
50  
51      /**
52       * logger used by this class
53       */
54      private static Log logger = LogFactory.getLog(DefaultMuleSession.class);
55  
56      /**
57       * The Mule service associated with the session
58       * <p/>
59       * Note: This object uses custom serialization via the writeObject()/readObject() methods.
60       */
61      private transient FlowConstruct flowConstruct = null;
62  
63      /**
64       * Determines if the service is valid
65       */
66      private boolean valid = true;
67  
68      private String id;
69  
70      /**
71       * The security context associated with the session.
72       * Note that this context will only be serialized if the SecurityContext object is Serializable.
73       */
74      private SecurityContext securityContext;
75  
76      private Map<String, Object> properties = null;
77  
78      /**
79       * The Mule context
80       * <p/>
81       * Note: This object uses custom serialization via the readObject() method.
82       */
83      private transient MuleContext muleContext;
84  
85      private transient Map<String, Object> serializedData = null;
86  
87      public DefaultMuleSession(MuleContext muleContext)
88      {
89          this((FlowConstruct) null, muleContext);
90      }
91  
92      public DefaultMuleSession(FlowConstruct flowConstruct, MuleContext muleContext)
93      {
94          this.muleContext = muleContext;
95          properties = new CaseInsensitiveHashMap/*<String, Object>*/();
96          id = UUID.getUUID();
97          this.flowConstruct = flowConstruct;
98      }
99  
100     /**
101      * @deprecated Use DefaultMuleSession(Service service, MuleContext muleContext) instead
102      */
103     @Deprecated
104     public DefaultMuleSession(MuleMessage message,
105                               SessionHandler requestSessionHandler,
106                               FlowConstruct flowConstruct,
107                               MuleContext muleContext) throws MuleException
108     {
109         this(message, requestSessionHandler, muleContext);
110         if (flowConstruct == null)
111         {
112             throw new IllegalArgumentException(CoreMessages.propertiesNotSet("flowConstruct").toString());
113         }
114         this.flowConstruct = flowConstruct;
115     }
116 
117     /**
118      * @deprecated Use DefaultMuleSession(MuleContext muleContext) instead
119      */
120     @Deprecated
121     public DefaultMuleSession(MuleMessage message, SessionHandler requestSessionHandler, MuleContext muleContext) throws MuleException
122     {
123         this(muleContext);
124 
125         if (requestSessionHandler == null)
126         {
127             throw new IllegalArgumentException(
128                     CoreMessages.propertiesNotSet("requestSessionHandler").toString());
129         }
130 
131         if (message == null)
132         {
133             throw new IllegalArgumentException(
134                     CoreMessages.propertiesNotSet("message").toString());
135         }
136 
137         properties = new CaseInsensitiveMap/*<String, Object>*/();
138         requestSessionHandler.retrieveSessionInfoFromMessage(message, this);
139         id = getProperty(requestSessionHandler.getSessionIDKey());
140         if (id == null)
141         {
142             id = UUID.getUUID();
143             if (logger.isDebugEnabled())
144             {
145                 logger.debug("There is no session id on the request using key: "
146                         + requestSessionHandler.getSessionIDKey() + ". Generating new session id: " + id);
147             }
148         }
149         else if (logger.isDebugEnabled())
150         {
151             logger.debug("Got session with id: " + id);
152         }
153     }
154 
155     public DefaultMuleSession(MuleSession session, MuleContext muleContext)
156     {
157         this.muleContext = muleContext;
158         this.id = session.getId();
159         this.securityContext = session.getSecurityContext();
160         this.flowConstruct = session.getFlowConstruct();
161         this.valid = session.isValid();
162 
163         this.properties = new HashMap<String, Object>();
164         for (String key : session.getPropertyNamesAsSet())
165         {
166             this.properties.put(key, session.getProperty(key));
167         }
168     }
169 
170     public String getId()
171     {
172         return id;
173     }
174 
175     public boolean isValid()
176     {
177         return valid;
178     }
179 
180     public void setValid(boolean value)
181     {
182         valid = value;
183     }
184 
185     /**
186      * @return Returns the service.
187      */
188     public FlowConstruct getFlowConstruct()
189     {
190         return flowConstruct;
191     }
192 
193     public void setFlowConstruct(FlowConstruct flowConstruct)
194     {
195         this.flowConstruct = flowConstruct;
196     }
197 
198     /**
199      * The security context for this session. If not null outbound, inbound and/or
200      * method invocations will be authenticated using this context
201      *
202      * @param context the context for this session or null if the request is not
203      *                secure.
204      */
205     public void setSecurityContext(SecurityContext context)
206     {
207         securityContext = context;
208     }
209 
210     /**
211      * The security context for this session. If not null outbound, inbound and/or
212      * method invocations will be authenticated using this context
213      *
214      * @return the context for this session or null if the request is not secure.
215      */
216     public SecurityContext getSecurityContext()
217     {
218         return securityContext;
219     }
220 
221     /**
222      * Will set a session level property. These will either be stored and retrieved
223      * using the underlying transport mechanism of stored using a default mechanism
224      *
225      * @param key   the key for the object data being stored on the session
226      * @param value the value of the session data
227      */
228     public void setProperty(String key, Object value)
229     {
230         properties.put(key, value);
231     }
232 
233     /**
234      * Will retrieve a session level property.
235      *
236      * @param key the key for the object data being stored on the session
237      * @return the value of the session data or null if the property does not exist
238      */
239     @SuppressWarnings("unchecked")
240     public <T> T getProperty(Object key)
241     {
242         return (T) properties.get(key);
243     }
244 
245     /**
246      * Will retrieve a session level property and remove it from the session
247      *
248      * @param key the key for the object data being stored on the session
249      * @return the value of the session data or null if the property does not exist
250      */
251     public Object removeProperty(Object key)
252     {
253         return properties.remove(key);
254     }
255 
256     /**
257      * Returns an iterater of property keys for the session properties on this
258      * session
259      *
260      * @return an iterater of property keys for the session properties on this
261      *         session
262      * @deprecated Use getPropertyNamesAsSet() instead
263      */
264     @Deprecated
265     public Iterator<String> getPropertyNames()
266     {
267         return properties.keySet().iterator();
268     }
269 
270     public Set<String> getPropertyNamesAsSet()
271     {
272         return Collections.unmodifiableSet(properties.keySet());
273     }
274 
275     ////////////////////////////
276     // Serialization methods
277     ////////////////////////////
278 
279     private void writeObject(ObjectOutputStream out) throws IOException
280     {
281         out.defaultWriteObject();
282         //Can be null if service call originates from MuleClient
283         if (getFlowConstruct() != null)
284         {
285             out.writeObject(getFlowConstruct() != null ? getFlowConstruct().getName() : "null");
286         }
287     }
288 
289     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
290     {
291         in.defaultReadObject();
292         serializedData = new HashMap<String, Object>();
293 
294         try
295         {
296             //Optional
297             serializedData.put("serviceName", in.readObject());
298         }
299         catch (OptionalDataException e)
300         {
301             //ignore
302         }
303     }
304 
305     /**
306      * Invoked after deserialization. This is called when the marker interface
307      * {@link org.mule.util.store.DeserializationPostInitialisable} is used. This will get invoked
308      * after the object has been deserialized passing in the current mulecontext when using either
309      * {@link org.mule.transformer.wire.SerializationWireFormat},
310      * {@link org.mule.transformer.wire.SerializedMuleMessageWireFormat}, or the
311      * {@link org.mule.transformer.simple.ByteArrayToSerializable} transformer.
312      *
313      * @param muleContext the current muleContext instance
314      * @throws MuleException if there is an error initializing
315      */
316     public void initAfterDeserialisation(MuleContext muleContext) throws MuleException
317     {
318         String serviceName = (String) serializedData.get("serviceName");
319         //Can be null if service call originates from MuleClient
320         if (serviceName != null)
321         {
322             flowConstruct = muleContext.getRegistry().lookupService(serviceName);
323         }
324         serializedData = null;
325     }
326 
327 }