001/**
002 *   GRANITE DATA SERVICES
003 *   Copyright (C) 2006-2014 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 */
022package org.granite.generator.java;
023
024import java.util.HashSet;
025import java.util.List;
026import java.util.Set;
027
028import org.granite.generator.as3.ClientType;
029import org.granite.generator.as3.PackageTranslator;
030
031/**
032 * @author Franck WOLFF
033 */
034public class JavaType implements ClientType {
035
036    ///////////////////////////////////////////////////////////////////////////
037    // Fields.
038
039    public static final JavaType BOOLEAN = new JavaType(null, "boolean", false);
040    public static final JavaType INT = new JavaType(null, "int", Integer.valueOf(0));
041    public static final JavaType LONG = new JavaType(null, "long", Long.valueOf(0));
042    public static final JavaType FLOAT = new JavaType(null, "float", Float.valueOf(0.0f));
043    public static final JavaType DOUBLE = new JavaType(null, "double", Double.valueOf(0.0));
044    public static final JavaType STRING = new JavaType(null, "String", null);
045    
046    public static final JavaType PAGE_INFO = new JavaType("org.granite.tide.data.model", "PageInfo", null);
047    public static final JavaType SORT_INFO = new JavaType("org.granite.tide.data.model", "SortInfo", null);
048    
049    public static final JavaType LAZY = new JavaType("org.granite.client.persistence", "Lazy", null);
050    
051    private final String packageName;
052    private final String name;
053    private final String qualifiedName;
054    private final String propertyImplTypeName;
055    private final Object nullValue;
056    private final Set<String> imports = new HashSet<String>(); 
057
058    ///////////////////////////////////////////////////////////////////////////
059    // Constructors.
060
061    public JavaType(String packageName, String simpleName) {
062        this(packageName, simpleName, null, null);
063    }
064    public JavaType(String packageName, String name, Object nullValue) {
065        this(packageName, name, null, nullValue);
066    }
067    public JavaType(String packageName, String name, String propertyImplTypeName, Object nullValue) {
068        this.packageName = (packageName != null ? packageName : "");
069        this.name = name;
070        this.qualifiedName = (hasPackage() ? (packageName + '.' + name) : name);
071        this.nullValue = nullValue;
072        this.propertyImplTypeName = propertyImplTypeName;
073        if (hasPackage())
074                imports.add(ungenerify(qualifiedName));
075        if (propertyImplTypeName != null)
076            imports.add(ungenerify(propertyImplTypeName));
077    }
078
079    ///////////////////////////////////////////////////////////////////////////
080    // Properties.
081
082    @Override
083        public boolean hasPackage() {
084        return packageName.length() > 0;
085    }
086
087    @Override
088        public String getPackageName() {
089        return packageName;
090    }
091
092    @Override
093        public String getName() {
094        return name;
095    }
096
097    @Override
098        public String getQualifiedName() {
099        return qualifiedName;
100    }
101    
102    public String getPropertyImplTypeName() {
103        return propertyImplTypeName;
104    }
105    
106    public String getSimplePropertyImplTypeName() {
107        return propertyImplTypeName != null && propertyImplTypeName.indexOf(".") >= 0 
108            ? propertyImplTypeName.substring(propertyImplTypeName.lastIndexOf(".")+1) : propertyImplTypeName;
109    }
110
111    @Override
112        public Object getNullValue() {
113        return nullValue;
114    }
115
116    public boolean isNumber() {
117        return false;
118    }
119    
120    ///////////////////////////////////////////////////////////////////////////
121    // Methods
122    
123    @Override
124        public Set<String> getImports() {
125        return imports;
126    }
127    
128    @Override
129        public void addImports(Set<String> classNames) {
130        for (String className : classNames) {
131                if (className.indexOf(".") < 0 || className.startsWith("java.lang"))
132                        continue;
133                imports.add(ungenerify(className));
134        }
135    }
136    
137    private String ungenerify(String className) {
138                if (className.indexOf("<") >= 0)
139                        return className.substring(0, className.indexOf("<"));
140                return className;
141    }
142    
143    @Override
144        public JavaType toArrayType() {
145        return new JavaType(packageName, name + "[]", null);
146    }
147    
148    @Override
149        public JavaType translatePackage(PackageTranslator translator) {
150        return new JavaType(translator.translate(packageName), getName(), getPropertyImplTypeName(), getNullValue());
151    }
152    
153    @Override
154    public JavaType translatePackages(List<PackageTranslator> translators) {
155        boolean translate = false;
156        
157        PackageTranslator translator = PackageTranslator.forPackage(translators, packageName);
158        String translatedPackageName = packageName;
159        if (translator != null) {
160                translate = true;
161                translatedPackageName = translator.translate(packageName);
162        }
163        
164        Set<String> translatedImports = new HashSet<String>();
165        for (String imp : imports) {
166                translator = PackageTranslator.forPackage(translators, imp);
167                if (translator != null) {
168                        translate = true;
169                        translatedImports.add(translator.translate(imp));
170                }
171                else
172                        translatedImports.add(imp);
173        }
174        
175        if (!translate)
176                return this;
177        
178        JavaType translatedType = new JavaType(translatedPackageName, getName(), getPropertyImplTypeName(), getNullValue());
179                translatedType.addImports(translatedImports);
180        return translatedType;
181    }
182
183    ///////////////////////////////////////////////////////////////////////////
184    // Utilities.
185
186    @Override
187    public int hashCode() {
188        return qualifiedName.hashCode();
189    }
190
191    @Override
192    public boolean equals(Object obj) {
193        if (obj == this)
194            return true;
195        if (!(obj instanceof JavaType))
196            return false;
197        return qualifiedName.equals(((JavaType)obj).qualifiedName);
198    }
199
200    @Override
201    public String toString() {
202        return qualifiedName;
203    }
204}