| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package flex.messaging.io; |
| |
| import flex.messaging.FlexContext; |
| import flex.messaging.MessageBroker; |
| import flex.messaging.io.amf.ASObject; |
| import flex.messaging.io.amf.translator.ASTranslator; |
| |
| import java.util.IdentityHashMap; |
| import java.util.Map; |
| |
| /** |
| * A simple context to hold type marshalling specific settings. |
| */ |
| public class TypeMarshallingContext |
| { |
| private static ThreadLocal<TypeMarshallingContext> contexts = new ThreadLocal<TypeMarshallingContext>(); |
| private static ThreadLocal<TypeMarshaller> marshallers = new ThreadLocal<TypeMarshaller>(); |
| private IdentityHashMap knownObjects; |
| private ClassLoader classLoader; |
| |
| /** |
| * Constructs a default type marshalling context. |
| */ |
| public TypeMarshallingContext() |
| { |
| } |
| |
| /** |
| * Establishes a TypeMarshallingContext for the current thread. |
| * Users are not expected to call this function. |
| * @param context The current TypeMarshallingContext. |
| */ |
| public static void setTypeMarshallingContext(TypeMarshallingContext context) |
| { |
| if (context == null) |
| contexts.remove(); |
| else |
| contexts.set(context); |
| } |
| |
| /** |
| * Get current TypeMarshallingContext object |
| * @return The current thread's TypeMarshallingContext. |
| */ |
| public static TypeMarshallingContext getTypeMarshallingContext() |
| { |
| TypeMarshallingContext context = contexts.get(); |
| if (context == null) |
| { |
| context = new TypeMarshallingContext(); |
| TypeMarshallingContext.setTypeMarshallingContext(context); |
| } |
| return context; |
| } |
| |
| /** |
| * Establishes a TypeMarshallingContext for the current thread. |
| * Users are not expected to call this function. |
| * |
| * @param marshaller The current TypeMarshaller. |
| */ |
| public static void setTypeMarshaller(TypeMarshaller marshaller) |
| { |
| if (marshaller == null) |
| marshallers.remove(); |
| else |
| marshallers.set(marshaller); |
| } |
| |
| /** |
| * Get current TypeMarshaller. |
| * @return The current thread's TypeMarshaller. |
| */ |
| public static TypeMarshaller getTypeMarshaller() |
| { |
| TypeMarshaller marshaller = marshallers.get(); |
| if (marshaller == null) |
| { |
| marshaller = new ASTranslator(); |
| setTypeMarshaller(marshaller); |
| } |
| |
| return marshaller; |
| } |
| |
| /** |
| * Returns the custom ClassLoader for this type marshalling session, or |
| * defaults to the current MessageBroker's ClassLoader if none has been set. |
| * @return ClassLoader the ClassLoader in use |
| */ |
| public ClassLoader getClassLoader() |
| { |
| if (classLoader != null) |
| return classLoader; |
| |
| try |
| { |
| MessageBroker messageBroker = FlexContext.getMessageBroker(); |
| return messageBroker != null? messageBroker.getClassLoader() : null; |
| } |
| catch (NoClassDefFoundError exception) // Could happen in client mode. |
| { |
| return null; |
| } |
| } |
| |
| /** |
| * Sets a custom classloader for this type marshalling session that will |
| * be used to create new instances of strongly typed objects. |
| * @param loader the ClassLoader to use |
| */ |
| public void setClassLoader(ClassLoader loader) |
| { |
| classLoader = loader; |
| } |
| |
| /** |
| * A map of known objects already encountered in this type marshalling |
| * session. |
| * @return IdentityHashMap the known objects |
| */ |
| public IdentityHashMap getKnownObjects() |
| { |
| if (knownObjects == null) |
| knownObjects = new IdentityHashMap(64); |
| |
| return knownObjects; |
| } |
| |
| /** |
| * Sets the list of the objects already encountered for this type |
| * marshalling session. |
| * @param knownObjects the IdentityHashMap object |
| */ |
| public void setKnownObjects(IdentityHashMap knownObjects) |
| { |
| this.knownObjects = knownObjects; |
| } |
| |
| /** |
| * Resets the list of known objects. |
| */ |
| public void reset() |
| { |
| if (knownObjects != null) |
| knownObjects.clear(); |
| } |
| |
| /** |
| * A utility method to determine whether an anonymous type specifies |
| * a strong type name, such as ASObject.getType() or the legacy Flash |
| * Remoting convention of using a _remoteClass property. |
| * @param obj the object to check |
| * @return The name of the strong type, or null if none was specified. |
| */ |
| public static String getType(Object obj) |
| { |
| String type = null; |
| |
| if (obj != null && obj instanceof Map) |
| { |
| Map map = (Map)obj; |
| |
| //Check for an Object.registerClass Typed ASObject |
| if (map instanceof ASObject) |
| { |
| ASObject aso = (ASObject)map; |
| type = aso.getType(); |
| } |
| |
| SerializationContext sc = SerializationContext.getSerializationContext(); |
| |
| if (type == null && sc.supportRemoteClass) |
| { |
| Object registerClass = map.get(MessageIOConstants.REMOTE_CLASS_FIELD); |
| if (registerClass != null && registerClass instanceof String) |
| { |
| type = (String)registerClass; |
| } |
| } |
| } |
| |
| return type; |
| } |
| |
| /** |
| * Clears out the thread local state after the request completes. |
| */ |
| public static void clearThreadLocalObjects() |
| { |
| if (contexts != null) |
| { |
| contexts.remove(); |
| } |
| if (marshallers != null) |
| { |
| marshallers.remove(); |
| } |
| } |
| |
| /** |
| * |
| * Destroy static thread local storage. |
| * Call ONLY on shutdown. |
| */ |
| public static void releaseThreadLocalObjects() |
| { |
| clearThreadLocalObjects(); |
| |
| contexts = null; |
| marshallers = null; |
| } |
| |
| /** |
| * |
| * Create static thread local storage. |
| */ |
| public static void createThreadLocalObjects() |
| { |
| if (contexts == null) |
| contexts = new ThreadLocal(); |
| if (marshallers == null) |
| marshallers = new ThreadLocal(); |
| } |
| } |