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