http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/BeanProxy.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/BeanProxy.java b/core/src/flex/messaging/io/BeanProxy.java deleted file mode 100644 index 05ccb01..0000000 --- a/core/src/flex/messaging/io/BeanProxy.java +++ /dev/null @@ -1,936 +0,0 @@ -/* - * 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.MessageException; -import flex.messaging.io.amf.ASObject; -import flex.messaging.log.Log; -import flex.messaging.log.Logger; -import flex.messaging.util.ClassUtil; -import flex.messaging.util.ExceptionUtil; - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.AbstractCollection; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -/** - * Uses Bean introspection to collect the properties for a given instance. - */ -public class BeanProxy extends AbstractProxy -{ - static final long serialVersionUID = 7365078101695257715L; - - private static final int FAILED_PROPERTY_READ_ERROR = 10021; - private static final int FAILED_PROPERTY_WRITE_ERROR = 10022; - private static final int NON_READABLE_PROPERTY_ERROR = 10023; - private static final int NON_WRITABLE_PROPERTY_ERROR = 10024; - private static final int UNKNOWN_PROPERTY_ERROR = 10025; - - protected static final Map<Class, List<String>> rwPropertyNamesCache = new IdentityHashMap<Class, List<String>>(); - protected static final Map<Class, Map<String, BeanProperty>> rwBeanPropertyCache = new IdentityHashMap<Class, Map<String, BeanProperty>>(); - protected static final Map<Class, PropertyDescriptorCacheEntry> rwPropertyDescriptorCache = new IdentityHashMap<Class, PropertyDescriptorCacheEntry>(); - - protected static final Map<Class, List<String>> roPropertyNamesCache = new IdentityHashMap<Class, List<String>>(); - protected static final Map<Class, Map<String, BeanProperty>> roBeanPropertyCache = new IdentityHashMap<Class, Map<String, BeanProperty>>(); - protected static final Map<Class, PropertyDescriptorCacheEntry> roPropertyDescriptorCache = new IdentityHashMap<Class, PropertyDescriptorCacheEntry>(); - - protected boolean cacheProperties = true; - protected boolean cachePropertiesDescriptors = true; - protected Class stopClass = Object.class; - - protected static final Map ignoreProperties = new HashMap(); - static - { - initializeIgnoreProperties(); - } - - private static void initializeIgnoreProperties() - { - addIgnoreProperty(AbstractMap.class, "empty"); - addIgnoreProperty(AbstractCollection.class, "empty"); - addIgnoreProperty(ASObject.class, "type"); - addIgnoreProperty(Throwable.class, "stackTrace"); - addIgnoreProperty(File.class, "parentFile"); - addIgnoreProperty(File.class, "canonicalFile"); - addIgnoreProperty(File.class, "absoluteFile"); - } - - /** - * Constructor. - */ - public BeanProxy() - { - this(null); - } - - /** - * Construct a new BeanProxy with the provided default instance. - * - * @param defaultInstance defines the alias if provided - */ - public BeanProxy(Object defaultInstance) - { - super(defaultInstance); - - // Override default behavior here... standard Map implementations - // are treated as anonymous Objects, i.e. without an alias. - if (defaultInstance != null) - alias = getClassName(defaultInstance); - } - - /** {@inheritDoc} */ - public String getAlias(Object instance) - { - return getClassName(instance); - } - - /** {@inheritDoc} */ - public List getPropertyNames(Object instance) - { - if (instance == null) - return null; - - Class c = instance.getClass(); - List<String> propertyNames = null; - - // Look up property names in cache if we don't have a custom serialization descriptor - if (descriptor == null) - { - if (getIncludeReadOnly()) - { - synchronized (roPropertyNamesCache) - { - propertyNames = roPropertyNamesCache.get(c); - } - } - else - { - synchronized (rwPropertyNamesCache) - { - propertyNames = rwPropertyNamesCache.get(c); - } - } - } - - if (propertyNames != null) - return propertyNames; - - // Make a copy of the property names to return - propertyNames = new ArrayList<String>(getBeanProperties(instance).keySet()); - - // Store property names in cache if we are caching properties - // and we don't have a custom serialization descriptor - if (cacheProperties && descriptor == null) - { - if (getIncludeReadOnly()) - { - synchronized (roPropertyNamesCache) - { - roPropertyNamesCache.put(c, propertyNames); - } - } - else - { - synchronized (rwPropertyNamesCache) - { - rwPropertyNamesCache.put(c, propertyNames); - } - } - } - return propertyNames; - } - - - /** {@inheritDoc} */ - public Class getType(Object instance, String propertyName) - { - if (instance == null || propertyName == null) - return null; - - BeanProperty bp = getBeanProperty(instance, propertyName); - return bp == null? null : bp.getType(); - } - - /** {@inheritDoc} */ - public Object getValue(Object instance, String propertyName) - { - if (instance == null || propertyName == null) - return null; - - BeanProperty bp = getBeanProperty(instance, propertyName); - if (bp != null) - return getBeanValue(instance, bp); - - SerializationContext context = getSerializationContext(); - if (!ignorePropertyErrors(context)) - { - // Property '{propertyName}' not found on class '{alias}'. - MessageException ex = new MessageException(); - ex.setMessage(UNKNOWN_PROPERTY_ERROR, new Object[] {propertyName, getAlias(instance)}); - throw ex; - } - return null; - } - - /** - * Gets the value specified by the BeanProperty. - * @param instance Object to get the value from - * @param bp the property to get - * @return the value of the property if it exists - */ - protected final Object getBeanValue(Object instance, BeanProperty bp) - { - String propertyName = bp.getName(); - if (bp.isRead()) - { - try - { - Object value = bp.get(instance); - if (value != null && descriptor != null) - { - SerializationDescriptor subDescriptor = (SerializationDescriptor)descriptor.get(propertyName); - if (subDescriptor != null) - { - PropertyProxy subProxy = PropertyProxyRegistry.getProxyAndRegister(value); - subProxy = (PropertyProxy)subProxy.clone(); - subProxy.setDescriptor(subDescriptor); - subProxy.setDefaultInstance(value); - value = subProxy; - } - } - return value; - } - catch (Exception e) - { - SerializationContext context = getSerializationContext(); - - // Log failed property set errors - if (Log.isWarn() && logPropertyErrors(context)) - { - Logger log = Log.getLogger(LOG_CATEGORY); - log.warn("Failed to get property {0} on type {1}.", - new Object[] {propertyName, getAlias(instance)}, e); - } - - if (!ignorePropertyErrors(context)) - { - // Failed to get property '{propertyName}' on type '{className}'. - MessageException ex = new MessageException(); - ex.setMessage(FAILED_PROPERTY_READ_ERROR, new Object[] {propertyName, getAlias(instance)}); - ex.setRootCause(e); - throw ex; - } - } - } - else - { - SerializationContext context = getSerializationContext(); - if (!ignorePropertyErrors(context)) - { - //Property '{propertyName}' not readable from class '{alias}'. - MessageException ex = new MessageException(); - ex.setMessage(NON_READABLE_PROPERTY_ERROR, new Object[] {propertyName, getAlias(instance)}); - throw ex; - } - } - return null; - } - - /** {@inheritDoc} */ - public void setValue(Object instance, String propertyName, Object value) - { - BeanProperty bp = getBeanProperty(instance, propertyName); - - if (bp != null) - { - if (bp.isWrite()) - { - try - { - Class desiredPropClass = bp.getType(); - TypeMarshaller marshaller = TypeMarshallingContext.getTypeMarshaller(); - value = marshaller.convert(value, desiredPropClass); - ClassUtil.validateAssignment(instance, propertyName, value); - bp.set(instance, value); - } - catch (Exception e) - { - SerializationContext context = getSerializationContext(); - - // Log ignore failed property set errors - if (Log.isWarn() && logPropertyErrors(context)) - { - Logger log = Log.getLogger(LOG_CATEGORY); - log.warn("Failed to set property {0} on type {1}.", - new Object[] {propertyName, getAlias(instance)}, e); - } - - if (!ignorePropertyErrors(context)) - { - // Failed to get property '{propertyName}' on type '{className}'. - MessageException ex = new MessageException(); - ex.setMessage(FAILED_PROPERTY_WRITE_ERROR, new Object[] {propertyName, getAlias(instance)}); - ex.setRootCause(e); - throw ex; - } - } - } - else - { - SerializationContext context = getSerializationContext(); - - if (Log.isWarn() && logPropertyErrors(context)) - { - Logger log = Log.getLogger(LOG_CATEGORY); - log.warn("Property {0} not writable on class {1}", - new Object[] {propertyName, getAlias(instance)}); - } - - if (!ignorePropertyErrors(context)) - { - //Property '{propertyName}' not writable on class '{alias}'. - MessageException ex = new MessageException(); - ex.setMessage(NON_WRITABLE_PROPERTY_ERROR, new Object[] {propertyName, getAlias(instance)}); - throw ex; - } - } - } - else - { - SerializationContext context = getSerializationContext(); - - if (Log.isWarn() && logPropertyErrors(context)) - { - Logger log = Log.getLogger(LOG_CATEGORY); - log.warn("Ignoring set property {0} for type {1} as a setter could not be found.", - new Object[] {propertyName, getAlias(instance)}); - } - - if (!ignorePropertyErrors(context)) - { - // Property '{propertyName}' not found on class '{alias}'. - MessageException ex = new MessageException(); - ex.setMessage(UNKNOWN_PROPERTY_ERROR, new Object[] {propertyName, getAlias(instance)}); - throw ex; - } - } - } - - /** - * Are we ignoring property errors? - * @param context serialization paramters. - * @return true if ignoring property errors. - */ - protected boolean ignorePropertyErrors(SerializationContext context) - { - return context.ignorePropertyErrors; - } - - /** - * Should we log property errors? - * @param context serialization parameters. - * @return true if we should log property errors. - */ - protected boolean logPropertyErrors(SerializationContext context) - { - return context.logPropertyErrors; - } - - /** - * Determins the classname for both normal types via Class.getName() and - * virtual types via ASObject.getType(). Virtual types starting - * with the special ">" token are also handled and the underlying - * className is returned. - * - * @param instance the object to examine. - * @return the classname to use for instances of this type - */ - protected String getClassName(Object instance) - { - String className; - - if (instance instanceof ASObject) - { - className = ((ASObject)instance).getType(); - } - else if (instance instanceof ClassAlias) - { - className = ((ClassAlias)instance).getAlias(); - } - else - { - className = instance.getClass().getName(); - // If there's an alias, use that as the class name. - ClassAliasRegistry registry = ClassAliasRegistry.getRegistry(); - String aliasedClass = registry.getClassName(className); - className = (aliasedClass == null)? className : aliasedClass; - } - - return className; - } - - /** - * Return a map of properties for a object. - * @param instance object to examine. - * @return a map of Strings to BeanProperty objects. - */ - protected Map<String, BeanProperty> getBeanProperties(Object instance) - { - Class c = instance.getClass(); - Map<String, BeanProperty> props; - - // look up instance class in cache if we don't have a custom descriptor. - if (descriptor == null) - { - if (getIncludeReadOnly()) - { - synchronized (roBeanPropertyCache) - { - props = roBeanPropertyCache.get(c); - } - } - else - { - synchronized (rwBeanPropertyCache) - { - props = rwBeanPropertyCache.get(c); - } - } - if (props != null) - return props; - } - - props = new HashMap<String, BeanProperty>(); - PropertyDescriptor[] pds = getPropertyDescriptors(c); - if (pds == null) - return null; - - List excludes = null; - if (descriptor != null) - { - excludes = descriptor.getExcludesForInstance(instance); - if (excludes == null) // For compatibility with older implementations - excludes = descriptor.getExcludes(); - } - - // Add standard bean properties first - for (PropertyDescriptor pd : pds) - { - String propertyName = pd.getName(); - Method readMethod = pd.getReadMethod(); - Method writeMethod = pd.getWriteMethod(); - - // If there's a public read method but no writeMethod and includeReadOnly - // flag is off, then skip the property. - if (readMethod != null && isPublicAccessor(readMethod.getModifiers()) && !getIncludeReadOnly() && writeMethod == null) - continue; - - // Skip excluded and ignored properties as well. - if ((excludes != null && excludes.contains(propertyName)) || isPropertyIgnored(c, propertyName)) - continue; - - // Ensure we don't include Object getClass() property, possibly returned (incorrectly) by custom BeanInfos - if (getIncludeReadOnly() && writeMethod == null && "class".equals(propertyName)) - continue; - - // Skip any classloader properties - final Class<?> type = pd.getPropertyType(); - if (type != null && ClassLoader.class.isAssignableFrom(type)) - continue; - - props.put(propertyName, new BeanProperty(propertyName, pd.getPropertyType(), - readMethod, writeMethod, null)); - } - - // Then add public fields to list if property does not already exist - Field[] fields = instance.getClass().getFields(); - for (Field field : fields) - { - String propertyName = field.getName(); - int modifiers = field.getModifiers(); - if (isPublicField(modifiers) && !props.containsKey(propertyName)) - { - // Skip excluded and ignored properties. - if ((excludes != null && excludes.contains(propertyName)) || isPropertyIgnored(c, propertyName)) - continue; - - props.put(propertyName, new BeanProperty(propertyName, field.getType(), null, null, field)); - } - } - - // Update the cache if we don't have a custom serialization descriptor and we are caching. - if (descriptor == null && cacheProperties) - { - if (getIncludeReadOnly()) - { - synchronized (roBeanPropertyCache) - { - roBeanPropertyCache.put(c, props); - } - } - else - { - synchronized (rwBeanPropertyCache) - { - rwBeanPropertyCache.put(c, props); - } - } - } - - return props; - } - - /** - * Return true if this property is write only, which means we cannot get a value for it. - * - * @param instance the instance - * @param propertyName the property name - * @return true if there is a way to write but not read the property - */ - public boolean isWriteOnly(Object instance, String propertyName) - { - if (instance == null || propertyName == null) - return false; - - BeanProperty bp = getBeanProperty(instance, propertyName); - return bp != null && bp.isWrite() && !bp.isRead(); - } - - /** - * Return a specific property descriptor for a named property. - * @param instance the object to use. - * @param propertyName the property to get. - * @return a descriptor for the property. - */ - protected final BeanProperty getBeanProperty(Object instance, String propertyName) - { - Class c = instance.getClass(); - Map props; - - // It is faster to use the BeanProperty cache if we are going to cache it. - if (descriptor == null && cacheProperties) - { - props = getBeanProperties(instance); - return props == null? null : (BeanProperty)props.get(propertyName); - } - - // Otherwise, just build up the property we are asked for - PropertyDescriptorCacheEntry pce = getPropertyDescriptorCacheEntry(c); - if (pce == null) - return null; - - Object pType = pce.propertiesByName.get(propertyName); - if (pType == null) - return null; - - List excludes = null; - if (descriptor != null) - { - excludes = descriptor.getExcludesForInstance(instance); - if (excludes == null) // For compatibility with older implementations - excludes = descriptor.getExcludes(); - } - - if (pType instanceof PropertyDescriptor) - { - PropertyDescriptor pd = (PropertyDescriptor) pType; - - Method readMethod = pd.getReadMethod(); - Method writeMethod = pd.getWriteMethod(); - - // If there's a public read method but no writeMethod and includeReadOnly - // flag is off, then skip the property. - if (readMethod != null && isPublicAccessor(readMethod.getModifiers()) && !getIncludeReadOnly() && writeMethod == null) - return null; - - // Skip excluded and ignored properties as well. - if ((excludes != null && excludes.contains(propertyName)) || isPropertyIgnored(c, propertyName)) - return null; - - return new BeanProperty(propertyName, pd.getPropertyType(), readMethod, writeMethod, null); - } - else if (pType instanceof Field) - { - Field field = (Field) pType; - - String pName = field.getName(); - int modifiers = field.getModifiers(); - if (isPublicField(modifiers) && pName.equals(propertyName)) - { - // Skip excluded and ignored properties. - return ((excludes != null && excludes.contains(propertyName)) || isPropertyIgnored(c, propertyName))? - null : new BeanProperty(propertyName, field.getType(), null, null, field); - } - } - - return null; - } - - /** - * Return an array of JavaBean property descriptors for a class. - * @param c the class to examine. - * @return an array ot JavaBean PropertyDescriptors. - */ - private PropertyDescriptor [] getPropertyDescriptors(Class c) - { - PropertyDescriptorCacheEntry pce = getPropertyDescriptorCacheEntry(c); - return pce == null? null : pce.propertyDescriptors; - } - - /** - * Return an entry from the property descriptor cache for a class. - * @param c the class - * @return a descriptor cache entry or null - */ - private PropertyDescriptorCacheEntry getPropertyDescriptorCacheEntry(Class c) - { - PropertyDescriptorCacheEntry pce; - if (getIncludeReadOnly()) - { - synchronized (roPropertyDescriptorCache) - { - pce = roPropertyDescriptorCache.get(c); - } - } - else - { - synchronized (rwPropertyDescriptorCache) - { - pce = rwPropertyDescriptorCache.get(c); - } - } - - try - { - if (pce == null) - { - BeanInfo beanInfo = Introspector.getBeanInfo(c, stopClass); - pce = new PropertyDescriptorCacheEntry(); - pce.propertyDescriptors = beanInfo.getPropertyDescriptors(); - pce.propertiesByName = createPropertiesByNameMap(pce.propertyDescriptors, c.getFields()); - if (cachePropertiesDescriptors) - { - if (getIncludeReadOnly()) - { - synchronized (roPropertyDescriptorCache) - { - roPropertyDescriptorCache.put(c, pce); - } - } - else - { - synchronized (rwPropertyDescriptorCache) - { - rwPropertyDescriptorCache.put(c, pce); - } - } - } - } - } - catch (IntrospectionException ex) - { - // Log failed property set errors - if (Log.isError()) - { - Logger log = Log.getLogger(LOG_CATEGORY); - log.error("Failed to introspect object of type: " + c + " error: " + ExceptionUtil.toString(ex)); - } - - // Return an empty descriptor rather than crashing - pce = new PropertyDescriptorCacheEntry(); - pce.propertyDescriptors = new PropertyDescriptor[0]; - pce.propertiesByName = new TreeMap(); - } - return pce; - } - - private Map createPropertiesByNameMap(PropertyDescriptor [] pds, Field [] fields) - { - Map m = new HashMap(pds.length); - for (PropertyDescriptor pd : pds) - { - Method readMethod = pd.getReadMethod(); - if (readMethod != null && isPublicAccessor(readMethod.getModifiers()) && - (getIncludeReadOnly() || pd.getWriteMethod() != null)) - m.put(pd.getName(), pd); - } - for (Field field : fields) - { - if (isPublicField(field.getModifiers()) && !m.containsKey(field.getName())) - m.put(field.getName(), field); - } - return m; - } - - /** - * Is this property on the ignore list for this class? - * @param c the class. - * @param propertyName the property name. - * @return true if we should ignore this property. - */ - public static boolean isPropertyIgnored(Class c, String propertyName) - { - boolean result = false; - Set propertyOwners = (Set)ignoreProperties.get(propertyName); - if (propertyOwners != null) - { - while (c != null) - { - if (propertyOwners.contains(c)) - { - result = true; - break; - } - c = c.getSuperclass(); - } - } - return result; - } - - /** - * Add a property to the ignore list for this class. - * @param c the class. - * @param propertyName the property to ignore. - */ - public static void addIgnoreProperty(Class c, String propertyName) - { - synchronized(ignoreProperties) - { - Set propertyOwners = (Set)ignoreProperties.get(propertyName); - if (propertyOwners == null) - { - propertyOwners = new HashSet(); - ignoreProperties.put(propertyName, propertyOwners); - } - propertyOwners.add(c); - } - } - - /** - * Do the provided modifiers indicate that this is public? - * @param modifiers the flags to check - * @return true if public but not final, static or transient. - */ - public static boolean isPublicField(int modifiers) - { - return (Modifier.isPublic(modifiers) && !Modifier.isFinal(modifiers) - && !Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)); - } - - /** - * Do the provided modifiers indicate that this is public? - * @param modifiers the flags to check - * @return true if public but not static. - */ - public static boolean isPublicAccessor(int modifiers) - { - return (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)); - } - - /** - * A class that holds information about a bean property. - */ - protected static class BeanProperty - { - private String name; - private Class type; - private Method readMethod, writeMethod; - private Field field; - - protected BeanProperty(String name, Class type, Method read, Method write, Field field) - { - this.name = name; - this.type = type; - this.writeMethod = write; - this.readMethod = read; - this.field = field; - } - - /** - * The name of the property.. - * @return the name. - */ - public String getName() - { - return name; - } - - /** - * The type of the property. - * @return the type - */ - public Class getType() - { - return type; - } - - /** - * Is there a setter for this property? - * @return true if there is a write method. - */ - public boolean isWrite() - { - return writeMethod != null || field != null; - } - - /** - * Is there a getter for this property? - * @return true if there is a read method. - */ - public boolean isRead() - { - return readMethod != null || field != null; - } - - /** - * Returns the Class object that declared the public field or getter function. - * @return an object of the declaring class for the read method or null if the read method is undefined. - */ - public Class getReadDeclaringClass() - { - if (readMethod != null) - return readMethod.getDeclaringClass(); - if (field != null) - return field.getDeclaringClass(); - return null; - } - - /** - * Return a class that represents the type of the property. - * @return the type of the property or null if there is no read method defined. - */ - public Class getReadType() - { - if (readMethod != null) - return readMethod.getReturnType(); - if (field != null) - return field.getType(); - return null; - } - - /** - * - * Returns a string indicating the setter or field name of the property. - * The setter is prefixed by 'method ', or the field is prefixed by 'field '. - * @return A string suitable for debugging. - */ - public String getWriteName() - { - if (writeMethod != null) - return "method " + writeMethod.getName(); - if (field != null) - return "field " + field.getName(); - return null; - } - - /** - * Set the property of the object to the specified value. - * @param bean the bean to set the property on. - * @param value the value to set. - * @throws IllegalAccessException if no access. - * @throws InvocationTargetException if the setter throws an exception. - */ - public void set(Object bean, Object value) throws IllegalAccessException, - InvocationTargetException - { - if (writeMethod != null) - writeMethod.invoke(bean, value); - else if (field != null) - field.set(bean, value); - else - throw new MessageException("Setter not found for property " + name); - } - - /** - * Get the value of this property from the specified object. - * @param bean the object to retrieve the value from - * @return the value of the property. - * @throws IllegalAccessException if no access. - * @throws InvocationTargetException if the getter throws an exception. - */ - public Object get(Object bean) throws IllegalAccessException, InvocationTargetException - { - Object obj = null; - if (readMethod != null) - obj = readMethod.invoke(bean, (Object[])null); - else if (field != null) - obj = field.get(bean); - return obj; - } - } - - /** - * Clears all static caches. - */ - public static void clear() - { - synchronized(ignoreProperties) - { - ignoreProperties.clear(); - initializeIgnoreProperties(); // reset to original state - } - synchronized(rwPropertyNamesCache) - { - rwPropertyNamesCache.clear(); - } - synchronized(rwBeanPropertyCache) - { - rwBeanPropertyCache.clear(); - } - synchronized(rwPropertyDescriptorCache) - { - rwPropertyDescriptorCache.clear(); - } - synchronized(roPropertyNamesCache) - { - roPropertyNamesCache.clear(); - } - synchronized(roBeanPropertyCache) - { - roBeanPropertyCache.clear(); - } - synchronized(roPropertyDescriptorCache) - { - roPropertyDescriptorCache.clear(); - } - } - - /** - * A cache entry. - */ - protected static class PropertyDescriptorCacheEntry - { - PropertyDescriptor [] propertyDescriptors; - Map propertiesByName; - } -}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/ClassAlias.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/ClassAlias.java b/core/src/flex/messaging/io/ClassAlias.java deleted file mode 100644 index 5bf8cdc..0000000 --- a/core/src/flex/messaging/io/ClassAlias.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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; - -/** - * A Class can implement this interface to customize the alias reported by - * a BeanProxy when describing a complex object's traits. - */ -public interface ClassAlias -{ - /** - * The alias to use for this instance. - */ - public String getAlias(); -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/ClassAliasRegistry.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/ClassAliasRegistry.java b/core/src/flex/messaging/io/ClassAliasRegistry.java deleted file mode 100644 index b97eaaa..0000000 --- a/core/src/flex/messaging/io/ClassAliasRegistry.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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.HashMap; -import java.util.Map; - -/** - * A simple registry that maps an alias to a concrete class name. This registry - * mimics the ActionScript 3 flash.net.registerClassAlias() functionality - * of the Flash Player. The registry is checked when deserializing AMF object - * types. - */ -public class ClassAliasRegistry -{ - private Map aliasRegistry = new HashMap(); - private static final ClassAliasRegistry registry = new ClassAliasRegistry(); - - /** - * Constructs an empty registry. - */ - private ClassAliasRegistry() - { - } - - /** - * Returns the registry singleton. - */ - public static ClassAliasRegistry getRegistry() - { - return registry; - } - - /** - * Looks for a concrete class name for an alias. - * - * @param alias The alias used to search the registry. - * @return a concrete class name, if registered for this alias, otherwise - * null. - */ - public String getClassName(String alias) - { - return (String)aliasRegistry.get(alias); - } - - /** - * Clears all items from the registry. - */ - public void clear() - { - synchronized(aliasRegistry) - { - aliasRegistry.clear(); - } - } - - /** - * Registers a custom alias for a class name. - * - * @param alias The alias for the class name. - * @param className The concrete class name. - */ - public void registerAlias(String alias, String className) - { - synchronized(aliasRegistry) - { - aliasRegistry.put(alias, className); - } - } - - /** - * Removes a class alias from the registry. - * - * @param alias The alias to be removed from the registry. - */ - public void unregisterAlias(String alias) - { - synchronized(aliasRegistry) - { - aliasRegistry.remove(alias); - } - } -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/DictionaryProxy.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/DictionaryProxy.java b/core/src/flex/messaging/io/DictionaryProxy.java deleted file mode 100644 index 41233d2..0000000 --- a/core/src/flex/messaging/io/DictionaryProxy.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.Dictionary; -import java.util.Enumeration; -import java.util.List; - -/** - * Proxies serialization of a Dictionary and considers all keys as String based property - * names. Additionally, bean properties from the instance are also included and override - * any Dictionary entries with the same name. - */ -public class DictionaryProxy extends BeanProxy -{ - static final long serialVersionUID = 1501461889185692712L; - - public DictionaryProxy() - { - super(); - //dynamic = true; - } - - public DictionaryProxy(Dictionary defaultInstance) - { - super(defaultInstance); - } - - public List getPropertyNames(Object instance) - { - if (instance == null) - return null; - - List propertyNames = null; - List excludes = null; - - if (descriptor != null) - { - excludes = descriptor.getExcludesForInstance(instance); - if (excludes == null) - excludes = descriptor.getExcludes(); - } - - // Add all Dictionary keys as properties - if (instance instanceof Dictionary) - { - Dictionary dictionary = (Dictionary)instance; - - propertyNames = new ArrayList(dictionary.size()); - - Enumeration keys = dictionary.keys(); - while (keys.hasMoreElements()) - { - Object key = keys.nextElement(); - if (key != null) - { - if (excludes != null && excludes.contains(key)) - continue; - - propertyNames.add(key.toString()); - } - } - } - - // Then, check for bean properties - List beanProperties = super.getPropertyNames(instance); - if (propertyNames == null) - { - propertyNames = beanProperties; - } - else - { - propertyNames.addAll(beanProperties); - } - - return propertyNames; - } - - public Object getValue(Object instance, String propertyName) - { - if (instance == null || propertyName == null) - return null; - - // First, check for bean property - Object value = super.getValue(instance, propertyName); - - // Then check for Dictionary entry - if (value == null && instance instanceof Dictionary) - { - Dictionary dictionary = (Dictionary)instance; - value = dictionary.get(propertyName); - } - - return value; - } -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/ManagedObjectProxy.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/ManagedObjectProxy.java b/core/src/flex/messaging/io/ManagedObjectProxy.java deleted file mode 100644 index 34bde91..0000000 --- a/core/src/flex/messaging/io/ManagedObjectProxy.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.util.Iterator; - -/** - * - */ -public class ManagedObjectProxy extends ObjectProxy -{ - static final long serialVersionUID = 255140415084514484L; - - public ManagedObjectProxy() - { - super(); - } - - public ManagedObjectProxy(int initialCapacity) - { - super(initialCapacity); - } - - public ManagedObjectProxy(int initialCapacity, float loadFactor) - { - super(initialCapacity, loadFactor); - } - - public void writeExternal(ObjectOutput out) throws IOException - { - int count = this.size(); - out.writeInt(count); - - // TODO: QUESTION: Jeff, We could copy the client approach to check a destination - // for lazy associations to exclude them from serialization. - - Iterator it = keySet().iterator(); - while (it.hasNext()) - { - Object key = it.next(); - out.writeObject(key); - out.writeObject(get(key)); - } - } - - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException - { - int count = in.readInt(); - - for (int i = 0; i < count; i++) - { - Object key = in.readObject(); - Object value = in.readObject(); - put(key, value); - } - } -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/MapProxy.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/MapProxy.java b/core/src/flex/messaging/io/MapProxy.java deleted file mode 100644 index 31bbef6..0000000 --- a/core/src/flex/messaging/io/MapProxy.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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.MessageException; -import flex.messaging.log.Log; -import flex.messaging.log.Logger; -import flex.messaging.util.ClassUtil; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * Proxies serialization of a Map and considers all keys as String based property - * names. Additionally, bean properties from the instance are also included and - * override any Map entries with the same key name. - */ -public class MapProxy extends BeanProxy -{ - static final long serialVersionUID = 7857999941099335210L; - - private static final int NULL_KEY_ERROR = 10026; - - /** - * Constructor - */ - public MapProxy() - { - super(); - //dynamic = true; - } - - /** - * Construct with a default instance type. - * @param defaultInstance defines the alias if provided - */ - public MapProxy(Object defaultInstance) - { - super(defaultInstance); - //dynamic = true; - } - - /** {@inheritDoc} */ - @Override - public List getPropertyNames(Object instance) - { - if (instance == null) - return null; - - List propertyNames = null; - List excludes = null; - - if (descriptor != null) - { - excludes = descriptor.getExcludesForInstance(instance); - if (excludes == null) // For compatibility with older implementations - excludes = descriptor.getExcludes(); - } - - // Add all Map keys as properties - if (instance instanceof Map) - { - Map map = (Map)instance; - - if (map.size() > 0) - { - propertyNames = new ArrayList(map.size()); - SerializationContext context = getSerializationContext(); - - Iterator it = map.keySet().iterator(); - while (it.hasNext()) - { - Object key = it.next(); - if (key != null) - { - if (excludes != null && excludes.contains(key)) - continue; - - propertyNames.add(key.toString()); - } - else - { - // Log null key errors - if (Log.isWarn() && context.logPropertyErrors) - { - Logger log = Log.getLogger(LOG_CATEGORY); - log.warn("Cannot send a null Map key for type {0}.", - new Object[] {map.getClass().getName()}); - } - - if (!context.ignorePropertyErrors) - { - // Cannot send a null Map key for type {0}. - MessageException ex = new MessageException(); - ex.setMessage(NULL_KEY_ERROR, new Object[] {map.getClass().getName()}); - throw ex; - } - } - } - } - } - - // Then, check for bean properties - List beanProperties = super.getPropertyNames(instance); - if (beanProperties != null) - { - if (propertyNames == null) - propertyNames = beanProperties; - else - propertyNames.addAll(beanProperties); - } - - return propertyNames; - } - - /** {@inheritDoc} */ - @Override - public Object getValue(Object instance, String propertyName) - { - if (instance == null || propertyName == null) - return null; - - Object value = null; - - // First, check for bean property - BeanProperty bp = getBeanProperty(instance, propertyName); - if (bp != null) - value = super.getBeanValue(instance, bp); - - // Then check for Map entry - if (value == null && instance instanceof Map) - value = getMapValue((Map)instance, propertyName); - - return value; - } - - /** {@inheritDoc} */ - @Override - public void setValue(Object instance, String propertyName, Object value) - { - if (instance == null || propertyName == null) - return; - - Map props = getBeanProperties(instance); - if (props.containsKey(propertyName)) - { - super.setValue(instance, propertyName, value); - } - else if (instance instanceof Map) - { - ClassUtil.validateAssignment(instance, propertyName, value); - ((Map)instance).put(propertyName, value); - } - } - - /** {@inheritDoc} */ - @Override - protected boolean ignorePropertyErrors(SerializationContext context) - { - return true; - } - - /** {@inheritDoc} */ - @Override - protected boolean logPropertyErrors(SerializationContext context) - { - return false; - } - - /** - * Return the classname of the instance, including ASObject types. - * If the instance is a Map and is in the java.util package, we return null. - * @param instance the object to find the class name of - * @return the class name of the object. - */ - @Override - protected String getClassName(Object instance) - { - return (instance != null && instance instanceof Map - && instance.getClass().getName().startsWith("java.util."))? - null : super.getClassName(instance); - } - - /** - * Given a map and a property name, returns the value keyed under that property - * name but instead of depending on {@link Map#get(Object)}, propertyName - * is compared against key#toString. This is due to the fact that propertyNames - * are always stored as Strings. - * - * @param map The Map to check against. - * @param propertyName The property name to check for. - * @return The value keyed under property name or null if it does not exist. - */ - protected Object getMapValue(Map map, String propertyName) - { - for (Object entry : map.entrySet()) - { - Object key = ((Map.Entry) entry).getKey(); - if (key.toString().equals(propertyName)) - return ((Map.Entry) entry).getValue(); - } - return null; - } -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/MessageDeserializer.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/MessageDeserializer.java b/core/src/flex/messaging/io/MessageDeserializer.java deleted file mode 100644 index 8262ab8..0000000 --- a/core/src/flex/messaging/io/MessageDeserializer.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.io.amf.ActionMessage; -import flex.messaging.io.amf.ActionContext; -import flex.messaging.io.amf.AmfTrace; - -import java.io.IOException; -import java.io.InputStream; - -/** - * An interface to allow for either AMF or AMFX based deserializers - * to process requests. - */ -public interface MessageDeserializer -{ - void initialize(SerializationContext context, InputStream in, AmfTrace trace); - - void readMessage(ActionMessage m, ActionContext context) throws ClassNotFoundException, IOException; - - Object readObject() throws ClassNotFoundException, IOException; -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/MessageIOConstants.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/MessageIOConstants.java b/core/src/flex/messaging/io/MessageIOConstants.java deleted file mode 100644 index 844590b..0000000 --- a/core/src/flex/messaging/io/MessageIOConstants.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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; - -/** - * - */ -public interface MessageIOConstants -{ - int AMF0 = 0; - int AMF1 = 1; // There is no AMF1 but FMS uses it for some reason, hence special casing. - int AMF3 = 3; - Double AMF3_INFO_PROPERTY = new Double(3); - - String CONTENT_TYPE_XML = "text/xml; charset=utf-8"; - String AMF_CONTENT_TYPE = "application/x-amf"; - String CONTENT_TYPE_PLAIN = "text/plain"; - String XML_CONTENT_TYPE = "application/xml"; - - String RESULT_METHOD = "/onResult"; - String STATUS_METHOD = "/onStatus"; - - int STATUS_OK = 0; - int STATUS_ERR = 1; - int STATUS_NOTAMF = 2; - - String SECURITY_HEADER_NAME = "Credentials"; - String SECURITY_PRINCIPAL = "userid"; - String SECURITY_CREDENTIALS = "password"; - - String URL_APPEND_HEADER = "AppendToGatewayUrl"; - String SERVICE_TYPE_HEADER = "ServiceType"; - - String REMOTE_CLASS_FIELD = "_remoteClass"; - String SUPPORT_REMOTE_CLASS = "SupportRemoteClass"; - String SUPPORT_DATES_BY_REFERENCE = "SupportDatesByReference"; - - String METHOD_POST = "POST"; - String HEADER_SOAP_ACTION = "SOAPAction"; -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/MessageSerializer.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/MessageSerializer.java b/core/src/flex/messaging/io/MessageSerializer.java deleted file mode 100644 index 5347db7..0000000 --- a/core/src/flex/messaging/io/MessageSerializer.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.io.amf.ActionMessage; -import flex.messaging.io.amf.AmfTrace; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * - */ -public interface MessageSerializer -{ - void setVersion(int value); - - void initialize(SerializationContext context, OutputStream out, AmfTrace trace); - - void writeMessage(ActionMessage m) throws IOException; - - void writeObject(Object value) throws IOException; -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/ObjectProxy.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/ObjectProxy.java b/core/src/flex/messaging/io/ObjectProxy.java deleted file mode 100644 index 6380de5..0000000 --- a/core/src/flex/messaging/io/ObjectProxy.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.io.Externalizable; -import java.io.ObjectInput; -import java.io.IOException; -import java.io.ObjectOutput; -import java.util.Map; -import java.util.HashMap; - -/** - * Flex's ObjectProxy class allows an anonymous, dynamic ActionScript Object - * to be bindable and report change events. Since ObjectProxy only wraps - * the ActionScript Object type we can map the class to a java.util.HashMap on the - * server, since the user would expect this type to be deserialized as a - * java.util.HashMap as it is... - */ -public class ObjectProxy extends HashMap implements Externalizable -{ - static final long serialVersionUID = 6978936573135117900L; - - public ObjectProxy() - { - super(); - } - - public ObjectProxy(int initialCapacity) - { - super(initialCapacity); - } - - public ObjectProxy(int initialCapacity, float loadFactor) - { - super(initialCapacity, loadFactor); - } - - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException - { - Object value = in.readObject(); - if (value instanceof Map) - { - putAll((Map)value); - } - } - - public void writeExternal(ObjectOutput out) throws IOException - { - // We can't output "this" to the serializer as it would - // cause a loop back to writeExternal as this is an Externalizable - // implementation itself! - - Map map = new HashMap(); - map.putAll(this); - out.writeObject(map); - } -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/PageableRowSet.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/PageableRowSet.java b/core/src/flex/messaging/io/PageableRowSet.java deleted file mode 100644 index 6102c33..0000000 --- a/core/src/flex/messaging/io/PageableRowSet.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.sql.SQLException; -import java.util.Map; - -/** - * Implementations of this class are recoginized by the serialization filter - * as result sets that are pageable. A pageable result set is a server side - * cache of a query result (that implements java.sql.ResultSet) and is - * typically stored in the session object. Users can request a subset of - * data from the object given that they know it's id. - * - * @see javax.sql.RowSet - */ -public interface PageableRowSet -{ - /** - * Constants for getRecords map keys. - */ - String PAGE = "Page"; - String CURSOR = "Cursor"; - - /** - * List the column names of the result set. - * - * @return String[] An array of the column names as strings, as ordered - * by the result set provider's column number assignment. - */ - String[] getColumnNames() throws SQLException; - - /** - * Use this method to get a subset of records. - * A map is returned with two fields, the first being the - * row number the data page started from, and the second - * being the array of arrays for the actual data page. - * @param startIndex the start index of the records - * @param count the total count - * @return Map Contains two fields, the page's row index and the actual data array. - */ - Map getRecords(int startIndex, int count) throws SQLException; - - /** - * Get the total number of rows in the result set - * @return int The total number of rows in the result set. - */ - int getRowCount(); - - /** - * If this function returns a number >= the total number of records in the recordset, - * then the recordset should be simply returned to the client in full. However, - * if it is < the total size, then this object itself is saved in Session data, - * and tagged with a unique ID. - * @return int the initial download count - */ - int getInitialDownloadCount(); - - - /** - * Get the paged result ID. - * @return String This paged result's (universally unique) id. - */ - String getID(); - - /** - * Get the name of the service that manages the pages - * @return String The name of the service that will manage this paged result. - */ - String getServiceName(); - - /** - * Set the name of the service that manages the pages. - * @param serviceName Update the name of the service that manages the pages for this query. - */ - void setServicename(String serviceName); -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/PageableRowSetProxy.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/PageableRowSetProxy.java b/core/src/flex/messaging/io/PageableRowSetProxy.java deleted file mode 100644 index 2c7d1d2..0000000 --- a/core/src/flex/messaging/io/PageableRowSetProxy.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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.MessageException; - -import javax.sql.RowSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * A wrapped PageableRowSet instance requires custom serialization so this - * legacy type has been made to fit the PropertyProxy interface. - * - * TODO: This proxy is similar to features made possible with Externalizable - * so PageableRowSet/RecordSet should be moved to an Externalizable - * implementation. - */ -public class PageableRowSetProxy extends AbstractProxy -{ - static final long serialVersionUID = 1121859941216924326L; - - public static final int HUGE_PAGE_SIZE = Integer.MAX_VALUE; - - /** - * AS Object Type Name. - */ - public static final String AS_TYPE_NAME = "RecordSet"; - - public static final Integer RECORD_SET_VERSION = new Integer(1); - - /** - * ActionScript (AS) Object Key Names. - */ - public static final String TOTAL_COUNT = "totalCount"; - public static final String COLUMN_NAMES = "columnNames"; - public static final String INITIAL_DATA = "initialData"; - public static final String SERVICE_NAME = "serviceName"; - public static final String SERVER_INFO = "serverInfo"; - public static final String VERSION = "version"; - public static final String CURSOR = "cursor"; - public static final String ID = "id"; - - public static final List propertyNameCache = new ArrayList(); - static - { - propertyNameCache.add(SERVER_INFO); - } - - public PageableRowSetProxy() - { - super(null); - alias = AS_TYPE_NAME; - } - - public PageableRowSetProxy(RowSet defaultInstance) - { - super(defaultInstance); - alias = AS_TYPE_NAME; - } - - public PageableRowSetProxy(PageableRowSet defaultInstance) - { - super(defaultInstance); - alias = AS_TYPE_NAME; - } - - public String getAlias(Object instance) - { - return AS_TYPE_NAME; - } - - public List getPropertyNames(Object instance) - { - return propertyNameCache; - } - - public Class getType(Object instance, String propertyName) - { - if (SERVER_INFO.equals(propertyName)) - { - return HashMap.class; - } - else - { - return null; - } - } - - public Object getValue(Object instance, String propertyName) - { - Object value = null; - - if (instance instanceof RowSet) - { - //Wrap in PageableRowSet just for its utility methods and don't create an id. - instance = new PagedRowSet((RowSet)instance, HUGE_PAGE_SIZE, false); - } - - if (instance instanceof PageableRowSet) - { - PageableRowSet prs = (PageableRowSet)instance; - - if (SERVER_INFO.equals(propertyName)) - { - try - { - HashMap serverInfo = new HashMap(); - serverInfo.put(ID, prs.getID()); - - Map pageInfo = prs.getRecords(1, prs.getInitialDownloadCount()); - - serverInfo.put(TOTAL_COUNT, new Integer(prs.getRowCount())); - serverInfo.put(INITIAL_DATA, pageInfo.get(PageableRowSet.PAGE)); //Array of Arrays - the first page returned - serverInfo.put(CURSOR, pageInfo.get(PageableRowSet.CURSOR)); //Integer - serverInfo.put(SERVICE_NAME, prs.getServiceName()); - serverInfo.put(COLUMN_NAMES, prs.getColumnNames()); - serverInfo.put(VERSION, RECORD_SET_VERSION); - value = serverInfo; - } - catch (SQLException ex) - { - MessageException e = new MessageException(); - e.setMessage("Error encountered serializing RowSet."); - e.setRootCause(ex); - throw e; - } - } - } - - return value; - } - - public void setValue(Object instance, String propertyName, Object value) - { - // Client-to-server not supported - } -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/PagedRowSet.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/io/PagedRowSet.java b/core/src/flex/messaging/io/PagedRowSet.java deleted file mode 100644 index 6224905..0000000 --- a/core/src/flex/messaging/io/PagedRowSet.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * 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.util.UUIDUtils; - -import javax.sql.RowSet; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * A wrapper for a RowSet to make it pageable. This technique is recommended - * if the RowSet is 'too big' to download all at once, AND the developer's - * client-side code is capable of dealing with non-fully-populated recordsets, - * that is, ActionScript RecordSets which are missing some of their data. - * - * @version 1.0 - */ -public class PagedRowSet implements PageableRowSet -{ - private RowSet rowSet; - private String[] colNames; - private int pageSize = 50; //Default to 50 records a page - private int colCount = 0; - private int rowCount = 0; - - private String id = null; - private String serviceName = null; - - /** - * Pageable Rowset Service Name. - */ - public static final String DEFAULT_PAGING_SERVICE_NAME = "PageableRowSetCache"; - - - /** - * Constructor - * <p> - * Creates a UUID for this object. Format: `XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' - * </p> - * - * @param r The RowSet to be paged. - * @param p The initial page size. - */ - public PagedRowSet(RowSet r, int p) - { - serviceName = DEFAULT_PAGING_SERVICE_NAME; - rowSet = r; - pageSize = p; - id = UUIDUtils.createUUID(); - init(); - } - - /** - * Allows the unique id generation of the RowSet to be toggled. - * @see #PagedRowSet(RowSet, int) - * - * @param r the row set - * @param p the page size - * @param createID should we create an id? - */ - public PagedRowSet(RowSet r, int p, boolean createID) - { - serviceName = DEFAULT_PAGING_SERVICE_NAME; - rowSet = r; - pageSize = p; - if (createID) - { - id = UUIDUtils.createUUID(); - } - init(); - } - - private void init() - { - if (rowSet != null) - { - //Initialize columns - initColumns(); - - //Initialize records - initRecords(); - } - else - { - colNames = new String[0]; - } - } - - - private synchronized void initColumns() - { - try - { - ResultSetMetaData rsmd = rowSet.getMetaData(); - if (rsmd != null) - { - colCount = rsmd.getColumnCount(); - } - } - catch (SQLException ex) - { - colCount = 0; - } - } - - - private synchronized void initRecords() - { - //Determine rs size - if (rowSet != null) - { - try - { - int currentIndex = rowSet.getRow(); - - //Go to the end and get that row number - if (rowSet.last()) - { - rowCount = rowSet.getRow(); - } - - //Put the cursor back - if (currentIndex > 0) - { - rowSet.absolute(currentIndex); - } - else - { - rowSet.beforeFirst(); - } - } - catch (SQLException ex) - { - //TODO: Decide whether if absolute() not be supported, try first() as a last resort?? - try - { - rowSet.first(); - } - catch (SQLException se) - { - //we won't try anymore. - } - } - } - } - - - /** - * List the column names of the result set. - * - * @return String[] An array of the column names as strings, as ordered - * by the result set provider's column number assignment. - */ - public synchronized String[] getColumnNames() - { - // Cache the column names lookup - if (colNames == null) - { - try - { - //Ensure column count is initialized - if (colCount == 0) - { - initColumns(); - } - - colNames = new String[colCount]; - - for (int i = 0; i < colCount; i++) - { - //Note: column numbers start at 1 - colNames[i] = rowSet.getMetaData().getColumnName(i + 1); - } - } - catch (SQLException ex) - { - colNames = new String[0]; - } - } - - // Create a copy - String[] ret = new String[colNames.length]; - System.arraycopy(colNames, 0, ret, 0, colNames.length); - return ret; - } - - - /** - * Use this method to get a map of the index used to start the data page, - * and an array of arrays of the actual data page itself. - * - * @param startIndex starting index - * @param count how many records to return - * @return Map A map with two fields, the index of the row to start the page, and an array of - * arrays for the actual data page. - * @throws SQLException if unable to get data from the rowset - */ - public synchronized Map getRecords(int startIndex, int count) throws SQLException - { - List aRecords = new ArrayList(); //Don't initialize with count as it could be Integer.MAX_VALUE - - //Ensure column count is initialized - if (colCount == 0) - { - initColumns(); - } - - //Starting index cannot be less than 1 - if (startIndex < 1) - startIndex = 1; - - //Populate the page, moving cursor to index - if (rowSet.absolute(startIndex)) - { - //Loop over the result set for the count specified - for (int i = 0; i < count; i++) - { - boolean hasNext; - - List row; - - if (colCount > 0) - { - row = new ArrayList(rowCount + 1); - //Loop over columns to create an array for the row - for (int j = 1; j <= colCount; j++) - { - Object data = rowSet.getObject(j); - if (data instanceof Clob) - { - Clob clob = (Clob) data; - row.add(clob.getSubString(0, (int) clob.length())); - } - else if (data instanceof Blob) - { - Blob blob = (Blob) data; - byte[] bytes = blob.getBytes(1, (int) blob.length()); - row.add(bytes); - } - else - row.add(data); - } - } - else //HACK: Handle any ColdFusion Query Objects that have no column metadata! - { - row = new ArrayList(); - - try - { - //Get as many columns as possible to build the row - //Stop on error or the first null column returned. - for (int j = 1; j <= 50; j++) - { - Object o = rowSet.getObject(j); - if (o != null) - { - row.add(o); - } - else - { - break; - } - } - } - catch (SQLException ex) - { - //Stop looking and just add the row. - } - } - - aRecords.add(row.toArray()); - - hasNext = rowSet.next(); - - //Cursor beyond last row, stop! - if (!hasNext) - { - break; - } - } - } - - Map result = new HashMap(2); - result.put(PAGE, aRecords.toArray()); - result.put(CURSOR, Integer.valueOf(startIndex)); - - return result; - } - - /** - * Get the row count. - * - * @return int The total number of rows in the result set. - */ - public int getRowCount() - { - return rowCount; - } - - /** - * If this function returns a number >= the total number of rows in the result set, - * then the result set should be simply returned to the client in full. However, - * if it is < the total size, then this object itself is saved in Session data, - * and tagged with a unique ID. - * - * @return the page size - */ - public int getInitialDownloadCount() - { - return pageSize; - } - - /** - * Return the id of this row set. - * @return the id - */ - public String getID() - { - return id; - } - - /** - * Get the service name. - * - * @return String The name of the service that will manage this paged result. - */ - public String getServiceName() - { - return serviceName; - } - - /** - * Set the service name. - * - * @param serviceName Update the name of the service that manages the pages for this query. - */ - public void setServicename(String serviceName) - { - this.serviceName = serviceName; - } -}