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