001    package org.andromda.cartridges.support.webservice.client;
002    
003    import java.lang.reflect.Method;
004    import org.apache.axis2.databinding.typemapping.SimpleTypeMapper;
005    
006    /**
007     * The default {@link TypeMapper} implementation.
008     *
009     * @author Chad Brandon
010     */
011    public class DefaultTypeMapper
012        implements TypeMapper
013    {
014        /**
015         * @see org.andromda.cartridges.support.webservice.client.TypeMapper#getObject(Class)
016         */
017        public Object getObject(Class type)
018        {
019            Object object = null;
020            if (type != null)
021            {
022                try
023                {
024                    object = type.newInstance();
025                }
026                catch (Exception exception)
027                {
028                    throw new TypeMapperException(exception);
029                }
030            }
031            return object;
032        }
033    
034        private static final String VALUE_OF = "valueOf";
035    
036        /**
037         * @see org.andromda.cartridges.support.webservice.client.TypeMapper#getObject(Class, String)
038         */
039        @SuppressWarnings("unchecked")
040        public Object getObject(Class type, String value)
041        {
042            Object object = null;
043            if (type != null && value != null)
044            {
045                try
046                {
047                    if (type.isEnum())
048                    {
049                        object = type.getMethod(
050                            VALUE_OF, new Class[]{String.class}).invoke(
051                                type, value);
052                    }
053                    else
054                    {
055                        final Method fromMethod = getEnumerationFromMethod(type);
056                        if (fromMethod != null)
057                        {
058                            object = fromMethod.invoke(type, value);
059                        }
060                    }
061                }
062                catch (Exception exception)
063                {
064                    throw new TypeMapperException(exception);
065                }
066            }
067            return object;
068        }
069    
070        /**
071         * @see org.andromda.cartridges.support.webservice.client.TypeMapper#getStringValue(Object)
072         */
073        public String getStringValue(Object object)
074        {
075            return SimpleTypeMapper.getStringValue(object);
076        }
077    
078        /**
079         * @see org.andromda.cartridges.support.webservice.client.TypeMapper#isSimpleType(Class)
080         */
081        public boolean isSimpleType(Class type)
082        {
083            return java.util.Calendar.class.isAssignableFrom(type) ||
084                java.util.Date.class.isAssignableFrom(type) ||
085                SimpleTypeMapper.isSimpleType(type) ||
086                isEnumeration(type);
087        }
088    
089        /**
090         * Indicates whether or not the given type represents an enumeration.
091         *
092         * @param type the type to check.
093         * @return true/false
094         */
095        private boolean isEnumeration(final Class type)
096        {
097            return isEnumeration(type, getEnumerationFromMethod(type));
098        }
099    
100        /**
101         * Indicates whether or not the given type represents an enumeration by checking
102         * whether the type is an actual "enum" class or the "fromMethod" is not null.
103         *
104         * @param type the type to check.
105         * @param the "from" method used to construct a typesafe enumeration from it's simple type.
106         * @return true/false
107         */
108        private boolean isEnumeration(final Class type, final Method fromMethod)
109        {
110            boolean enumeration = false;
111            if (type != null)
112            {
113                enumeration = type.isEnum();
114                if (!enumeration)
115                {
116                    enumeration = fromMethod != null;
117                }
118            }
119            return enumeration;
120        }
121    
122        private static final String FROM = "from";
123    
124        /**
125         * Gets the "from" method for a type safe enumeration.
126         *
127         * @param type the type.
128         * @return the "from" method (i.e. fromString, etc).
129         */
130        private Method getEnumerationFromMethod(final Class type)
131        {
132            Method fromMethod = null;
133            if (type != null)
134            {
135                // - check for the typesafe enum pattern
136                for (final Method method : type.getMethods())
137                {
138                    if (method.getName().startsWith(FROM))
139                    {
140                        final Class[] parameterTypes = method.getParameterTypes();
141                        if (parameterTypes.length == 1)
142                        {
143                            final Class parameterType = parameterTypes[0];
144                            if (method.getName().equals(FROM + parameterType.getSimpleName()))
145                            {
146                                fromMethod = method;
147                                break;
148                            }
149                        }
150                    }
151                }
152            }
153            return fromMethod;
154        }
155    
156    }