| /* |
| * 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 java.util.List; |
| import java.io.Externalizable; |
| import java.io.Serializable; |
| |
| import flex.messaging.MessageException; |
| import flex.messaging.io.amf.ASObject; |
| import flex.messaging.log.LogCategories; |
| import flex.messaging.log.Log; |
| import flex.messaging.log.Logger; |
| import flex.messaging.util.ClassUtil; |
| |
| /** |
| * Simple abstract implementation of PropertyProxy's common properties. Specific |
| * sub-classes need to provide the full implementation focusing on the retrieval |
| * of the instance traits or "list of properties" and a specific value for |
| * a given property name. |
| * |
| * @see flex.messaging.io.PropertyProxy |
| */ |
| public abstract class AbstractProxy implements PropertyProxy, Serializable { |
| protected Object defaultInstance; |
| protected String alias; |
| protected boolean dynamic; |
| protected boolean externalizable; |
| protected boolean includeReadOnly; |
| protected SerializationDescriptor descriptor; |
| protected SerializationContext context; |
| |
| protected static final String LOG_CATEGORY = LogCategories.ENDPOINT_TYPE; |
| private static final int CONVERSION_ERROR = 10006; |
| |
| protected AbstractProxy(Object defaultInstance) { |
| this.defaultInstance = defaultInstance; |
| if (defaultInstance != null) |
| alias = defaultInstance.getClass().getName(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public Object getDefaultInstance() { |
| return defaultInstance; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setDefaultInstance(Object instance) { |
| defaultInstance = instance; |
| } |
| |
| /** |
| * A utility method which returns the Class from the given Class name |
| * using the current type context's class loader. |
| * |
| * @param className the class name. |
| * @return a Class object for the named class. |
| */ |
| public static Class getClassFromClassName(String className) { |
| TypeMarshallingContext typeContext = TypeMarshallingContext.getTypeMarshallingContext(); |
| return ClassUtil.createClass(className, typeContext.getClassLoader()); |
| } |
| |
| /** |
| * A utility method which creates an instance from a given class name. It assumes |
| * the class has a zero arg constructor. |
| * |
| * @param className the class name |
| * for a type that is missing on the server, instead of throwing a server resource not found |
| * exception. |
| * @return the instance of the named class. |
| */ |
| public static Object createInstanceFromClassName(String className) { |
| Class<?> desiredClass = getClassFromClassName(className); |
| return ClassUtil.createDefaultInstance(desiredClass, null, true /*validate*/); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public Object createInstance(String className) { |
| Object instance; |
| |
| if (className == null || className.length() == 0) { |
| instance = ClassUtil.createDefaultInstance(ASObject.class, null, true /*validate*/); |
| } else if (className.startsWith(">")) // Handle [RemoteClass] (no server alias) |
| { |
| instance = ClassUtil.createDefaultInstance(ASObject.class, null, true /*validate*/); |
| ((ASObject) instance).setType(className); |
| } else { |
| if (getSerializationContext().instantiateTypes || className.startsWith("flex.")) |
| return createInstanceFromClassName(className); |
| |
| // Just return type info with an ASObject... |
| instance = ClassUtil.createDefaultInstance(ASObject.class, null, true /*validate*/); |
| ((ASObject) instance).setType(className); |
| } |
| return instance; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List getPropertyNames() { |
| return getPropertyNames(getDefaultInstance()); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public Class getType(String propertyName) { |
| return getType(getDefaultInstance(), propertyName); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public Object getValue(String propertyName) { |
| return getValue(getDefaultInstance(), propertyName); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setValue(String propertyName, Object value) { |
| setValue(getDefaultInstance(), propertyName, value); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setAlias(String value) { |
| alias = value; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public String getAlias() { |
| return alias; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setDynamic(boolean value) { |
| dynamic = value; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean isDynamic() { |
| return dynamic; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean isExternalizable() { |
| return externalizable; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setExternalizable(boolean value) { |
| externalizable = value; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean isExternalizable(Object instance) { |
| return instance instanceof Externalizable; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public SerializationContext getSerializationContext() { |
| return context == null ? SerializationContext.getSerializationContext() : context; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setSerializationContext(SerializationContext value) { |
| context = value; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setIncludeReadOnly(boolean value) { |
| includeReadOnly = value; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean getIncludeReadOnly() { |
| if (includeReadOnly) { |
| return true; |
| } |
| return getSerializationContext().includeReadOnly; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public SerializationDescriptor getDescriptor() { |
| return descriptor; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setDescriptor(SerializationDescriptor descriptor) { |
| this.descriptor = descriptor; |
| } |
| |
| /** |
| * This is called after the serialization finishes. We return the same object |
| * here... this is an opportunity to replace the instance we use once we have |
| * gathered all of the state into a temporary object. |
| * |
| * @param instance current instance |
| * @return Object the instance after complete serialization |
| */ |
| public Object instanceComplete(Object instance) { |
| return instance; |
| } |
| |
| /** |
| * Returns the instance to serialize in place of the supplied instance. |
| * |
| * @param instance the instance to serialize |
| * @return Object the instance |
| */ |
| public Object getInstanceToSerialize(Object instance) { |
| return instance; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public Object clone() { |
| try { |
| AbstractProxy clonedProxy = (AbstractProxy) super.clone(); |
| clonedProxy.setCloneFieldsFrom(this); |
| return clonedProxy; |
| } catch (CloneNotSupportedException e) { |
| if (Log.isError()) { |
| Logger log = Log.getLogger(LOG_CATEGORY); |
| log.error("Failed to clone a property proxy: " + toString()); |
| } |
| MessageException ex = new MessageException(); |
| ex.setMessage(CONVERSION_ERROR); |
| throw ex; |
| } |
| } |
| |
| /** |
| * A string including the default instance, class and descriptor info. |
| * |
| * @return debug string. |
| */ |
| @Override |
| public String toString() { |
| if (defaultInstance != null) |
| return "[Proxy(inst=" + defaultInstance + ") proxyClass=" + getClass() + " descriptor=" + descriptor + "]"; |
| return "[Proxy(proxyClass=" + getClass() + " descriptor=" + descriptor + "]"; |
| } |
| |
| protected void setCloneFieldsFrom(AbstractProxy source) { |
| setDescriptor(source.getDescriptor()); |
| setDefaultInstance(source.getDefaultInstance()); |
| context = source.context; |
| includeReadOnly = source.includeReadOnly; |
| } |
| } |