001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2007-2010 ADEQUATE SYSTEMS SARL
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.math.BigDecimal;
024    import java.math.BigInteger;
025    import java.math.MathContext;
026    import java.math.RoundingMode;
027    import java.net.URI;
028    import java.net.URL;
029    import java.util.Calendar;
030    import java.util.Collection;
031    import java.util.Date;
032    import java.util.HashMap;
033    import java.util.Locale;
034    import java.util.Map;
035    
036    import org.granite.util.ClassUtil;
037    import org.w3c.dom.Document;
038    
039    /**
040     * @author Franck WOLFF
041     */
042    public class DefaultAs3TypeFactory implements As3TypeFactory {
043    
044        ///////////////////////////////////////////////////////////////////////////
045        // Fields.
046    
047        private final Map<Class<?>, As3Type> java2As3Type = new HashMap<Class<?>, As3Type>();
048    
049        ///////////////////////////////////////////////////////////////////////////
050        // Constructors.
051    
052        public DefaultAs3TypeFactory() {
053            java2As3Type.put(Double.class, As3Type.NUMBER);
054            java2As3Type.put(Double.TYPE, As3Type.NUMBER);
055            java2As3Type.put(Float.class, As3Type.NUMBER);
056            java2As3Type.put(Float.TYPE, As3Type.NUMBER);
057            java2As3Type.put(Long.class, As3Type.NUMBER);
058            java2As3Type.put(Long.TYPE, As3Type.NUMBER);
059            java2As3Type.put(Integer.class, As3Type.NUMBER);
060            java2As3Type.put(Integer.TYPE, As3Type.INT);
061            java2As3Type.put(Short.class, As3Type.NUMBER);
062            java2As3Type.put(Short.TYPE, As3Type.INT);
063            java2As3Type.put(Byte.class, As3Type.NUMBER);
064            java2As3Type.put(Byte.TYPE, As3Type.INT);
065    
066            java2As3Type.put(MathContext.class, As3Type.MATH_CONTEXT);
067            java2As3Type.put(RoundingMode.class, As3Type.ROUNDING_MODE);
068    
069            java2As3Type.put(Boolean.class, As3Type.BOOLEAN);
070            java2As3Type.put(Boolean.TYPE, As3Type.BOOLEAN);
071    
072            java2As3Type.put(String.class, As3Type.STRING);
073            java2As3Type.put(Character.class, As3Type.STRING);
074            java2As3Type.put(Character.TYPE, As3Type.STRING);
075            java2As3Type.put(Locale.class, As3Type.STRING);
076            java2As3Type.put(URL.class, As3Type.STRING);
077            java2As3Type.put(URI.class, As3Type.STRING);
078    
079            java2As3Type.put(Object.class, As3Type.OBJECT);
080    
081            java2As3Type.put(Enum.class, As3Type.ENUM);
082        }
083    
084        ///////////////////////////////////////////////////////////////////////////
085        // Fields.
086    
087        public void configure(boolean externalizeLong, boolean externalizeBigInteger, boolean externalizeBigDecimal) {
088            if (externalizeLong) {
089                    java2As3Type.put(Long.class, As3Type.LONG);
090                    java2As3Type.put(Long.TYPE, As3Type.LONG);
091            }
092            if (externalizeBigInteger)
093                    java2As3Type.put(BigInteger.class, As3Type.BIG_INTEGER);
094            if (externalizeBigDecimal)
095                    java2As3Type.put(BigDecimal.class, As3Type.BIG_DECIMAL);
096            }
097    
098            public As3Type getAs3Type(Class<?> jType) {
099            As3Type as3Type = getFromCache(jType);
100    
101            if (as3Type == null) {
102                if (Date.class.isAssignableFrom(jType) || Calendar.class.isAssignableFrom(jType)) {
103                    as3Type = As3Type.DATE;
104                }
105                else if (Number.class.isAssignableFrom(jType)) {
106                    as3Type = As3Type.NUMBER;
107                }
108                else if (Document.class.isAssignableFrom(jType)) {
109                    as3Type = As3Type.XML;
110                }
111                else if (jType.isArray()) {
112                    Class<?> componentType = jType.getComponentType();
113                    if (Byte.class.equals(componentType) || Byte.TYPE.equals(componentType))
114                        as3Type = As3Type.BYTE_ARRAY;
115                    else if (Character.class.equals(componentType) || Character.TYPE.equals(componentType))
116                        as3Type = As3Type.STRING;
117                    else
118                        as3Type = As3Type.ARRAY;
119                }
120                else if (Collection.class.isAssignableFrom(jType)) {
121                    as3Type = As3Type.ARRAY_COLLECTION;
122                }
123                else if (Map.class.isAssignableFrom(jType)) {
124                    as3Type = As3Type.IMAP;
125                }
126                else if (jType.getName().equals("com.google.appengine.api.datastore.Key")) {
127                    as3Type = As3Type.STRING;
128                }
129                else {
130                    as3Type = createAs3Type(jType);
131                }
132    
133                putInCache(jType, as3Type);
134            }
135    
136            return as3Type;
137        }
138    
139        protected As3Type createAs3Type(Class<?> jType) {
140            String name = jType.getSimpleName();
141            if (jType.isMemberClass())
142                    name = jType.getEnclosingClass().getSimpleName() + '$' + jType.getSimpleName();
143            return new As3Type(ClassUtil.getPackageName(jType), name);
144        }
145    
146        protected As3Type getFromCache(Class<?> jType) {
147            if (jType == null)
148                throw new NullPointerException("jType must be non null");
149            return java2As3Type.get(jType);
150        }
151    
152        protected void putInCache(Class<?> jType, As3Type as3Type) {
153            if (jType == null || as3Type == null)
154                throw new NullPointerException("jType and as3Type must be non null");
155            java2As3Type.put(jType, as3Type);
156        }
157    }