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
021package org.granite.generator.as3;
022
023import java.io.Serializable;
024import java.lang.reflect.ParameterizedType;
025import java.lang.reflect.Type;
026import java.math.BigDecimal;
027import java.math.BigInteger;
028import java.math.MathContext;
029import java.math.RoundingMode;
030import java.net.URI;
031import java.net.URL;
032import java.util.Calendar;
033import java.util.Collection;
034import java.util.Date;
035import java.util.HashMap;
036import java.util.Locale;
037import java.util.Map;
038
039import org.granite.util.ClassUtil;
040import org.w3c.dom.Document;
041
042/**
043 * @author Franck WOLFF
044 */
045public 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, PropertyType propertyType) {
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}