001    /**
002     *   GRANITE DATA SERVICES
003     *   Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004     *
005     *   This file is part of the Granite Data Services Platform.
006     *
007     *   Granite Data Services is free software; you can redistribute it and/or
008     *   modify it under the terms of the GNU Lesser General Public
009     *   License as published by the Free Software Foundation; either
010     *   version 2.1 of the License, or (at your option) any later version.
011     *
012     *   Granite Data Services is distributed in the hope that it will be useful,
013     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
015     *   General Public License for more details.
016     *
017     *   You should have received a copy of the GNU Lesser General Public
018     *   License along with this library; if not, write to the Free Software
019     *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
020     *   USA, or see <http://www.gnu.org/licenses/>.
021     */
022    
023    package org.granite.generator.as3;
024    
025    import java.io.Serializable;
026    import java.lang.reflect.ParameterizedType;
027    import java.lang.reflect.Type;
028    import java.math.BigDecimal;
029    import java.math.BigInteger;
030    import java.math.MathContext;
031    import java.math.RoundingMode;
032    import java.net.URI;
033    import java.net.URL;
034    import java.util.Calendar;
035    import java.util.Collection;
036    import java.util.Date;
037    import java.util.HashMap;
038    import java.util.Locale;
039    import java.util.Map;
040    
041    import org.granite.util.ClassUtil;
042    import org.w3c.dom.Document;
043    
044    /**
045     * @author Franck WOLFF
046     */
047    public class DefaultAs3TypeFactory implements As3TypeFactory {
048    
049        ///////////////////////////////////////////////////////////////////////////
050        // Fields.
051    
052        private final Map<Class<?>, As3Type> java2As3Type = new HashMap<Class<?>, As3Type>();
053    
054        ///////////////////////////////////////////////////////////////////////////
055        // Constructors.
056    
057        public DefaultAs3TypeFactory() {
058            java2As3Type.put(Double.class, As3Type.NUMBER);
059            java2As3Type.put(Double.TYPE, As3Type.NUMBER);
060            java2As3Type.put(Float.class, As3Type.NUMBER);
061            java2As3Type.put(Float.TYPE, As3Type.NUMBER);
062            java2As3Type.put(Long.class, As3Type.NUMBER);
063            java2As3Type.put(Long.TYPE, As3Type.NUMBER);
064            java2As3Type.put(Integer.class, As3Type.NUMBER);
065            java2As3Type.put(Integer.TYPE, As3Type.INT);
066            java2As3Type.put(Short.class, As3Type.NUMBER);
067            java2As3Type.put(Short.TYPE, As3Type.INT);
068            java2As3Type.put(Byte.class, As3Type.NUMBER);
069            java2As3Type.put(Byte.TYPE, As3Type.INT);
070    
071            java2As3Type.put(MathContext.class, As3Type.MATH_CONTEXT);
072            java2As3Type.put(RoundingMode.class, As3Type.ROUNDING_MODE);
073    
074            java2As3Type.put(Boolean.class, As3Type.BOOLEAN);
075            java2As3Type.put(Boolean.TYPE, As3Type.BOOLEAN);
076    
077            java2As3Type.put(String.class, As3Type.STRING);
078            java2As3Type.put(Character.class, As3Type.STRING);
079            java2As3Type.put(Character.TYPE, As3Type.STRING);
080            java2As3Type.put(Locale.class, As3Type.STRING);
081            java2As3Type.put(URL.class, As3Type.STRING);
082            java2As3Type.put(URI.class, As3Type.STRING);
083    
084            java2As3Type.put(Object.class, As3Type.OBJECT);
085            java2As3Type.put(Serializable.class, As3Type.OBJECT);
086    
087            java2As3Type.put(Enum.class, As3Type.ENUM);
088        }
089    
090        ///////////////////////////////////////////////////////////////////////////
091        // Fields.
092    
093        @Override
094            public void configure(boolean externalizeLong, boolean externalizeBigInteger, boolean externalizeBigDecimal) {
095            if (externalizeLong) {
096                    java2As3Type.put(Long.class, As3Type.LONG);
097                    java2As3Type.put(Long.TYPE, As3Type.LONG);
098            }
099            if (externalizeBigInteger)
100                    java2As3Type.put(BigInteger.class, As3Type.BIG_INTEGER);
101            if (externalizeBigDecimal)
102                    java2As3Type.put(BigDecimal.class, As3Type.BIG_DECIMAL);
103            }
104        
105        @Override
106            public ClientType getClientType(Type jType, Class<?> declaringClass, ParameterizedType[] declaringTypes, PropertyType propertyType) {
107            return null;
108        }
109    
110            @Override
111            public ClientType getAs3Type(Class<?> jType) {
112            As3Type as3Type = getFromCache(jType);
113    
114            if (as3Type == null) {
115                if (Date.class.isAssignableFrom(jType) || Calendar.class.isAssignableFrom(jType)) {
116                    as3Type = As3Type.DATE;
117                }
118                else if (Number.class.isAssignableFrom(jType)) {
119                    as3Type = As3Type.NUMBER;
120                }
121                else if (Document.class.isAssignableFrom(jType)) {
122                    as3Type = As3Type.XML;
123                }
124                else if (jType.isArray()) {
125                    Class<?> componentType = jType.getComponentType();
126                    if (Byte.class.equals(componentType) || Byte.TYPE.equals(componentType))
127                        as3Type = As3Type.BYTE_ARRAY;
128                    else if (Character.class.equals(componentType) || Character.TYPE.equals(componentType))
129                        as3Type = As3Type.STRING;
130                    else
131                        as3Type = As3Type.ARRAY;
132                }
133                else if (Collection.class.isAssignableFrom(jType)) {
134                    as3Type = As3Type.LIST_COLLECTION_VIEW;
135                }
136                else if (Iterable.class.isAssignableFrom(jType)) {
137                    as3Type = As3Type.ILIST;
138                }
139                else if (Map.class.isAssignableFrom(jType)) {
140                    as3Type = As3Type.IMAP;
141                }
142                else if (jType.getName().equals("com.google.appengine.api.datastore.Key")) {
143                    as3Type = As3Type.STRING;
144                }
145                else if (jType.getName().equals("org.springframework.data.domain.Page")) {
146                    as3Type = As3Type.PAGE;
147                }
148                else if (jType.getName().equals("org.springframework.data.domain.Pageable")) {
149                    as3Type = As3Type.PAGE_INFO;
150                }
151                else if (jType.getName().equals("org.springframework.data.domain.Sort")) {
152                    as3Type = As3Type.SORT_INFO;
153                }
154                else {
155                    as3Type = createAs3Type(jType);
156                }
157    
158                putInCache(jType, as3Type);
159            }
160    
161            return as3Type;
162        }
163    
164        protected As3Type createAs3Type(Class<?> jType) {
165            String name = jType.getSimpleName();
166            if (jType.isMemberClass())
167                    name = jType.getEnclosingClass().getSimpleName() + '$' + jType.getSimpleName();
168            return new As3Type(ClassUtil.getPackageName(jType), name);
169        }
170    
171        protected As3Type getFromCache(Class<?> jType) {
172            if (jType == null)
173                throw new NullPointerException("jType must be non null");
174            return java2As3Type.get(jType);
175        }
176    
177        protected void putInCache(Class<?> jType, As3Type as3Type) {
178            if (jType == null || as3Type == null)
179                throw new NullPointerException("jType and as3Type must be non null");
180            java2As3Type.put(jType, as3Type);
181        }
182    }