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    
023    package org.granite.generator.javafx;
024    
025    import java.util.HashSet;
026    import java.util.List;
027    import java.util.Set;
028    
029    import org.granite.generator.as3.ClientType;
030    import org.granite.generator.as3.PackageTranslator;
031    
032    /**
033     * @author Franck WOLFF
034     */
035    public 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    }