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.javafx;
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 JavaFXType implements ClientType {
035
036    ///////////////////////////////////////////////////////////////////////////
037    // Fields.
038
039    public static final JavaFXType BOOLEAN = new JavaFXType(null, "boolean", false);
040    public static final JavaFXType INT = new JavaFXType(null, "int", Integer.valueOf(0));
041    public static final JavaFXType LONG = new JavaFXType(null, "long", Long.valueOf(0));
042    public static final JavaFXType FLOAT = new JavaFXType(null, "float", Float.valueOf(0.0f));
043    public static final JavaFXType DOUBLE = new JavaFXType(null, "double", Double.valueOf(0.0));
044    public static final JavaFXType STRING = new JavaFXType(null, "String", null);
045    
046    public static final JavaFXType PAGE_INFO = new JavaFXType("org.granite.tide.data.model", "PageInfo", null);
047    public static final JavaFXType SORT_INFO = new JavaFXType("org.granite.tide.data.model", "SortInfo", null);
048    
049    public static final JavaFXType LAZY = new JavaFXType("org.granite.client.persistence", "Lazy", null);
050    
051    public static final JavaFXType BOOLEAN_PROPERTY = new JavaFXType(null, "boolean", "javafx.beans.property.BooleanProperty", "javafx.beans.property.SimpleBooleanProperty", Boolean.FALSE);
052    public static final JavaFXType INT_PROPERTY = new JavaFXType(null, "int", "javafx.beans.property.IntegerProperty", "javafx.beans.property.SimpleIntegerProperty", Integer.valueOf(0));
053    public static final JavaFXType LONG_PROPERTY = new JavaFXType(null, "long", "javafx.beans.property.LongProperty", "javafx.beans.property.SimpleLongProperty", Long.valueOf(0));
054    public static final JavaFXType FLOAT_PROPERTY = new JavaFXType(null, "float", "javafx.beans.property.FloatProperty", "javafx.beans.property.SimpleFloatProperty", Float.valueOf(0.0f));
055    public static final JavaFXType DOUBLE_PROPERTY = new JavaFXType(null, "double", "javafx.beans.property.DoubleProperty", "javafx.beans.property.SimpleDoubleProperty", Double.valueOf(0.0));
056    public static final JavaFXType STRING_PROPERTY = new JavaFXType(null, "String", "javafx.beans.property.StringProperty", "javafx.beans.property.SimpleStringProperty", null);
057    
058    public static final JavaFXType BOOLEAN_READONLY_PROPERTY = new JavaFXType(null, "boolean", "javafx.beans.property.ReadOnlyBooleanProperty", "javafx.beans.property.ReadOnlyBooleanWrapper", null, Boolean.FALSE, true);
059    public static final JavaFXType INT_READONLY_PROPERTY = new JavaFXType(null, "int", "javafx.beans.property.ReadOnlyIntegerProperty", "javafx.beans.property.ReadOnlyIntegerWrapper", null, Integer.valueOf(0), true);
060    public static final JavaFXType LONG_READONLY_PROPERTY = new JavaFXType(null, "long", "javafx.beans.property.ReadOnlyLongProperty", "javafx.beans.property.ReadOnlyLongWrapper", null, Long.valueOf(0), true);
061    public static final JavaFXType FLOAT_READONLY_PROPERTY = new JavaFXType(null, "float", "javafx.beans.property.ReadOnlyFloatProperty", "javafx.beans.property.ReadOnlyFloatWrapper", null, Float.valueOf(0.0f), true);
062    public static final JavaFXType DOUBLE_READONLY_PROPERTY = new JavaFXType(null, "double", "javafx.beans.property.ReadOnlyDoubleProperty", "javafx.beans.property.ReadOnlyDoubleWrapper", null, Double.valueOf(0.0), true);
063    public static final JavaFXType STRING_READONLY_PROPERTY = new JavaFXType(null, "String", "javafx.beans.property.ReadOnlyStringProperty", "javafx.beans.property.ReadOnlyStringWrapper", null, null, true);
064    
065    private final String packageName;
066    private final String name;
067    private final String qualifiedName;
068    private final String propertyTypeName;
069    private final String propertyImplTypeName;
070    private final String propertyFactoryName;
071    private final Object nullValue;
072    private final boolean readOnly;
073    private final Set<String> imports = new HashSet<String>(); 
074
075    ///////////////////////////////////////////////////////////////////////////
076    // Constructors.
077
078    public JavaFXType(String packageName, String simpleName) {
079        this(packageName, simpleName, null);
080    }
081    public JavaFXType(String packageName, String name, Object nullValue) {
082        this(packageName, name, null, null, nullValue);
083    }
084    public JavaFXType(String packageName, String name, String propertyTypeName, String propertyImplTypeName, Object nullValue) {
085        this(packageName, name, propertyTypeName, propertyImplTypeName, null, nullValue, false);
086    }
087    public JavaFXType(String packageName, String name, String propertyTypeName, String propertyImplTypeName, String propertyFactoryName, Object nullValue, boolean readOnly) {
088        this.packageName = (packageName != null ? packageName : "");
089        this.name = name;
090        this.qualifiedName = (hasPackage() ? (packageName + '.' + name) : name);
091        this.nullValue = nullValue;
092        this.propertyTypeName = propertyTypeName;
093        this.propertyImplTypeName = propertyImplTypeName;
094        this.propertyFactoryName = propertyFactoryName;
095        this.readOnly = readOnly;
096        if (hasPackage())
097                imports.add(ungenerify(qualifiedName));
098        if (propertyTypeName != null)
099                imports.add(ungenerify(propertyTypeName));
100        if (propertyImplTypeName != null)
101                imports.add(ungenerify(propertyImplTypeName));
102    }
103
104    ///////////////////////////////////////////////////////////////////////////
105    // Properties.
106
107    @Override
108        public boolean hasPackage() {
109        return packageName.length() > 0;
110    }
111
112    @Override
113        public String getPackageName() {
114        return packageName;
115    }
116
117    @Override
118        public String getName() {
119        return name;
120    }
121
122    @Override
123        public String getQualifiedName() {
124        return qualifiedName;
125    }
126    
127    public String getPropertyTypeName() {
128        return propertyTypeName;
129    }
130    
131    public String getSimplePropertyTypeName() {
132        return propertyTypeName != null && propertyTypeName.indexOf(".") >= 0 
133                ? propertyTypeName.substring(propertyTypeName.lastIndexOf(".")+1) : propertyTypeName;
134    }
135    
136    public String getPropertyImplTypeName() {
137        return propertyImplTypeName;
138    }
139    
140    public String getSimplePropertyImplTypeName() {
141        return propertyImplTypeName != null && propertyImplTypeName.indexOf(".") >= 0 
142                ? propertyImplTypeName.substring(propertyImplTypeName.lastIndexOf(".")+1) : propertyImplTypeName;
143    }
144    
145    public String getPropertyFactoryName() {
146        return propertyFactoryName != null ? propertyFactoryName : "new " + getSimplePropertyImplTypeName();
147    }
148
149    @Override
150        public Object getNullValue() {
151        return nullValue;
152    }
153    
154    public boolean isReadOnly() {
155        return readOnly;
156    }
157
158    public boolean isNumber() {
159        return false;
160    }
161    
162    ///////////////////////////////////////////////////////////////////////////
163    // Methods
164    
165    @Override
166        public Set<String> getImports() {
167        return imports;
168    }
169    
170    @Override
171        public void addImports(Set<String> classNames) {
172        for (String className : classNames) {
173                if (className.indexOf(".") < 0 || className.startsWith("java.lang"))
174                        continue;
175                imports.add(ungenerify(className));
176        }
177    }
178    
179    private String ungenerify(String className) {
180                if (className.indexOf("<") >= 0)
181                        return className.substring(0, className.indexOf("<"));
182                return className;
183    }
184    
185    @Override
186        public JavaFXType toArrayType() {
187        return new JavaFXType(packageName, name + "[]", null);
188    }
189    
190    @Override
191        public JavaFXType translatePackage(PackageTranslator translator) {
192        return new JavaFXType(translator.translate(packageName), getName(), getPropertyTypeName(), getPropertyImplTypeName(), getPropertyFactoryName(), getNullValue(), isReadOnly());
193    }
194    
195    @Override
196    public JavaFXType translatePackages(List<PackageTranslator> translators) {
197        boolean translate = false;
198        
199        PackageTranslator translator = PackageTranslator.forPackage(translators, packageName);
200        String translatedPackageName = packageName;
201        if (translator != null) {
202                translate = true;
203                translatedPackageName = translator.translate(packageName);
204        }
205        
206        Set<String> translatedImports = new HashSet<String>();
207        for (String imp : imports) {
208                translator = PackageTranslator.forPackage(translators, imp);
209                if (translator != null) {
210                        translate = true;
211                        translatedImports.add(translator.translate(imp));
212                }
213                else
214                        translatedImports.add(imp);
215        }
216        
217        if (!translate)
218                return this;
219        
220        JavaFXType translatedType = new JavaFXType(translatedPackageName, getName(), getPropertyTypeName(), getPropertyImplTypeName(), getPropertyFactoryName(), getNullValue(), isReadOnly());
221                translatedType.addImports(translatedImports);
222        return translatedType;
223    }
224
225    ///////////////////////////////////////////////////////////////////////////
226    // Utilities.
227
228    @Override
229    public int hashCode() {
230        return qualifiedName.hashCode();
231    }
232
233    @Override
234    public boolean equals(Object obj) {
235        if (obj == this)
236            return true;
237        if (!(obj instanceof JavaFXType))
238            return false;
239        return qualifiedName.equals(((JavaFXType)obj).qualifiedName);
240    }
241
242    @Override
243    public String toString() {
244        return qualifiedName;
245    }
246}