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