diff --git a/README.md b/README.md
index e971be6..971d026 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,8 @@ private StringProperty name;
public StringProperty getName() {
return name;
}
-public void setName( StringProperty name ) {
+
+public void setName(StringProperty name) {
this.name = name;
}
```
@@ -24,11 +25,11 @@ public final String getName() {
return name.get();
}
-public final void setName( String value ) {
+public final void setName(String value) {
name.set(value);
}
-public final StringProperty nameProperty() {
+public StringProperty nameProperty() {
return name;
}
```
@@ -38,19 +39,46 @@ which will create the following methods:
```java
private StringProperty nameProperty;
+
public final String getName() {
return nameProperty.get();
}
-public final void setName( String value ) {
+public final void setName(String value) {
nameProperty.set(value);
}
-public final StringProperty nameProperty() {
+public StringProperty nameProperty() {
return nameProperty;
}
```
+Read-only properties and read-only wrapper types are also supported:
+
+```java
+private ReadOnlyStringProperty identifier;
+
+public final String getIdentifier() {
+ return identifier.get();
+}
+
+public ReadOnlyStringProperty identifierProperty() {
+ return identifier;
+}
+```
+
+```java
+private ReadOnlyStringWrapper identifier;
+
+public final String getIdentifier() {
+ return identifier.get();
+}
+
+public ReadOnlyStringProperty identifierProperty() {
+ return identifier.getReadOnlyProperty();
+}
+```
+
# Usage
@@ -71,12 +99,35 @@ Methods for supported property types will automatically be generated.
* FloatProperty
* IntegerProperty
* LongProperty
-
-
-
-### Unsupported Property Types
* ListProperty
* MapProperty
* ObjectProperty
* SetProperty
+
+
+### Supported Read-only Property Types
+* ReadOnlyStringProperty
+* ReadOnlyBooleanProperty
+* ReadOnlyDoubleProperty
+* ReadOnlyFloatProperty
+* ReadOnlyIntegerProperty
+* ReadOnlyLongProperty
+* ReadOnlyListProperty
+* ReadOnlyMapProperty
+* ReadOnlyObjectProperty
+* ReadOnlySetProperty
+
+
+
+### Supported Read-only Wrapper Types
+* ReadOnlyStringWrapper
+* ReadOnlyBooleanWrapper
+* ReadOnlyDoubleWrapper
+* ReadOnlyFloatWrapper
+* ReadOnlyIntegerWrapper
+* ReadOnlyLongWrapper
+* ReadOnlyListWrapper
+* ReadOnlyMapWrapper
+* ReadOnlyObjectWrapper
+* ReadOnlySetWrapper
diff --git a/nb-configuration.xml b/nb-configuration.xml
deleted file mode 100644
index a65c451..0000000
--- a/nb-configuration.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
- JDK_1.8
-
-
diff --git a/pom.xml b/pom.xml
index be46058..12db3d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
Rob Terpilowski
MIT License
LICENSE
- mykeystore
+ mykeystore
myself
@@ -61,47 +61,52 @@
org.netbeans.api
org-netbeans-api-annotations-common
- RELEASE802
+ RELEASE81
org.netbeans.api
org-netbeans-modules-editor-lib2
- RELEASE802
+ RELEASE81
org.netbeans.api
org-netbeans-modules-editor-mimelookup
- RELEASE802
+ RELEASE81
org.netbeans.api
org-openide-util-lookup
- RELEASE802
+ RELEASE81
org.netbeans.api
org-netbeans-libs-javacapi
- RELEASE802
+ RELEASE81
org.netbeans.api
org-netbeans-modules-java-source
- RELEASE802
+ RELEASE81
org.netbeans.api
org-openide-util
- RELEASE802
+ RELEASE81
org.netbeans.api
org-netbeans-modules-editor-lib
- RELEASE802
+ RELEASE81
org.netbeans.api
org-netbeans-libs-javafx
- RELEASE802
+ RELEASE81
+
+
+ org.netbeans.api
+ org-netbeans-modules-java-source-base
+ RELEASE81
diff --git a/src/main/java/com/lynden/netbeans/javafx/CodeGeneratorCancellableTask.java b/src/main/java/com/lynden/netbeans/javafx/CodeGeneratorCancellableTask.java
index e3922e1..65723b7 100644
--- a/src/main/java/com/lynden/netbeans/javafx/CodeGeneratorCancellableTask.java
+++ b/src/main/java/com/lynden/netbeans/javafx/CodeGeneratorCancellableTask.java
@@ -1,36 +1,34 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Lynden, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
package com.lynden.netbeans.javafx;
-/**
-The MIT License (MIT)
-
-Copyright (c) 2015 Lynden, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-**/
-
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;
import java.io.IOException;
import javax.swing.text.JTextComponent;
import org.netbeans.api.java.source.CancellableTask;
import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.TreeUtilities;
import org.netbeans.api.java.source.WorkingCopy;
/**
@@ -38,6 +36,7 @@ of this software and associated documentation files (the "Software"), to deal
* @author Francesco Illuminati
*/
abstract class CodeGeneratorCancellableTask implements CancellableTask {
+
private final JTextComponent textComponent;
public CodeGeneratorCancellableTask(JTextComponent textComponent) {
@@ -51,17 +50,16 @@ public void run(WorkingCopy workingCopy) throws IOException {
generate(workingCopy);
}
- public abstract void generateCode(WorkingCopy workingCopy, TreePath path,
- int position);
-
private void generate(WorkingCopy wc) throws IOException {
- final int caretOffset = textComponent.getCaretPosition();
- TreePath path = wc.getTreeUtilities().pathFor(caretOffset);
- path = TreeHelper.getParentElementOfKind(Tree.Kind.CLASS, path);
- int idx = TreeHelper.findClassMemberIndex(wc,(ClassTree) path.getLeaf(), caretOffset);
- generateCode(wc, path, idx);
+ TreeUtilities treeUtils = wc.getTreeUtilities();
+
+ int caretPosition = textComponent.getCaretPosition();
+ TreePath treePathAtCaret = treeUtils.pathFor(caretPosition);
+ generateCode(wc, treePathAtCaret, caretPosition);
}
+ protected abstract void generateCode(WorkingCopy workingCopy, TreePath treePathAtCaret, int caretPosition);
+
@Override
public void cancel() {
}
diff --git a/src/main/java/com/lynden/netbeans/javafx/JavaFxBeanHelper.java b/src/main/java/com/lynden/netbeans/javafx/JavaFxBeanHelper.java
index ce67324..ccd9d6c 100644
--- a/src/main/java/com/lynden/netbeans/javafx/JavaFxBeanHelper.java
+++ b/src/main/java/com/lynden/netbeans/javafx/JavaFxBeanHelper.java
@@ -1,4 +1,4 @@
-/**
+/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Lynden, Inc.
@@ -20,19 +20,22 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
-*
*/
package com.lynden.netbeans.javafx;
import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;
+import com.sun.source.util.Trees;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
import java.util.List;
-import javafx.beans.property.*;
+import java.util.Set;
+import java.util.stream.Collectors;
import javafx.embed.swing.JFXPanel;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
@@ -46,6 +49,7 @@
import org.netbeans.api.java.source.JavaSource;
import org.netbeans.api.java.source.ModificationResult;
import org.netbeans.api.java.source.TreeMaker;
+import org.netbeans.api.java.source.TreeUtilities;
import org.netbeans.api.java.source.WorkingCopy;
import org.netbeans.spi.editor.codegen.CodeGenerator;
import org.netbeans.spi.editor.codegen.CodeGeneratorContextProvider;
@@ -54,20 +58,46 @@
public class JavaFxBeanHelper implements CodeGenerator {
+ private static final Set SUPPORTED_CLASSES = new HashSet<>();
+
+ static {
+ SUPPORTED_CLASSES.add("javafx.beans.property.IntegerProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.LongProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.FloatProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.DoubleProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.BooleanProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.StringProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ListProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.SetProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.MapProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ObjectProperty");
+
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyIntegerProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyLongProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyFloatProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyDoubleProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyBooleanProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyStringProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyListProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlySetProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyMapProperty");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyObjectProperty");
+
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyIntegerWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyLongWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyFloatWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyDoubleWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyBooleanWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyStringWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyListWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlySetWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyMapWrapper");
+ SUPPORTED_CLASSES.add("javafx.beans.property.ReadOnlyObjectWrapper");
+ }
+
protected JTextComponent textComponent;
//this is needed to initialize the JavaFx Toolkit
protected JFXPanel panel = new JFXPanel();
- protected List fields;
-
- public JavaFxBeanHelper textComponent(final JTextComponent value) {
- this.textComponent = value;
- return this;
- }
-
- public JavaFxBeanHelper fields(final List value) {
- this.fields = value;
- return this;
- }
/**
*
@@ -76,12 +106,6 @@ public JavaFxBeanHelper fields(final List value) {
*/
private JavaFxBeanHelper(Lookup context) { // Good practice is not to save Lookup outside ctor
textComponent = context.lookup(JTextComponent.class);
- CompilationController controller = context.lookup(CompilationController.class);
- try {
- fields = getFields(context, controller);
- } catch (CodeGeneratorException ex) {
- Exceptions.printStackTrace(ex);
- }
}
@MimeRegistration(mimeType = "text/x-java", position = 250, service = CodeGenerator.Factory.class)
@@ -89,7 +113,20 @@ public static class Factory implements CodeGenerator.Factory {
@Override
public List extends CodeGenerator> create(Lookup context) {
- return Collections.singletonList(new JavaFxBeanHelper(context));
+ CompilationController controller = context.lookup(CompilationController.class);
+ TreePath path = context.lookup(TreePath.class);
+
+ TreeUtilities treeUtils = controller.getTreeUtilities();
+
+ TreePath classTreePath = treeUtils.getPathElementOfKind(EnumSet.of(Tree.Kind.CLASS, Tree.Kind.ENUM), path);
+
+ /* Are we in a class and does the class have supported property
+ * fields? */
+ if ((classTreePath != null) && (!getFields(controller, classTreePath).isEmpty())) {
+ return Collections.singletonList(new JavaFxBeanHelper(context));
+ } else {
+ return Collections.emptyList();
+ }
}
}
@@ -112,8 +149,8 @@ public void invoke() {
CancellableTask task = new CodeGeneratorCancellableTask(textComponent) {
@Override
- public void generateCode(WorkingCopy workingCopy, TreePath path, int position) {
- JavaFxBeanHelper.this.generateCode(workingCopy, path, position, JavaFxBeanHelper.this.fields);
+ protected void generateCode(WorkingCopy workingCopy, TreePath treePathAtCaret, int caretPosition) {
+ JavaFxBeanHelper.this.generateCode(workingCopy, treePathAtCaret, caretPosition);
}
};
@@ -126,89 +163,60 @@ public void generateCode(WorkingCopy workingCopy, TreePath path, int position) {
}
- protected void generateCode(WorkingCopy wc, TreePath path, int position, List fields) {
+ protected void generateCode(WorkingCopy wc, TreePath treePathAtCaret, int caretPosition) {
+ TreeUtilities treeUtils = wc.getTreeUtilities();
- TypeElement typeClassElement = (TypeElement) wc.getTrees().getElement(path);
- if (typeClassElement != null) {
- int index = position;
+ TreePath classTreePath = treeUtils.getPathElementOfKind(EnumSet.of(Tree.Kind.CLASS, Tree.Kind.ENUM), treePathAtCaret);
+ if (classTreePath != null) {
- TreeMaker make = wc.getTreeMaker();
- ClassTree classTree = (ClassTree) path.getLeaf();
- List members = new ArrayList<>(classTree.getMembers());
- String className = typeClassElement.toString();
+ int classMemberIndexAtCaret = TreeHelper.findClassMemberIndex(wc, (ClassTree) classTreePath.getLeaf(), caretPosition);
- PropertyMethodBuilder propertyMethodBuilder = new PropertyMethodBuilder(make, members, fields, className);
+ generateCodeInClass(wc, classTreePath, classMemberIndexAtCaret);
+ }
+ }
- index = propertyMethodBuilder.removeExistingPropMethods(index);
+ protected void generateCodeInClass(WorkingCopy wc, TreePath classTreePath, int classMemberIndexAtCaret) {
- propertyMethodBuilder.addPropMethods(index);
+ List fields = getFields(wc, classTreePath);
- ClassTree newClassTree = make.Class(classTree.getModifiers(),
- classTree.getSimpleName(),
- classTree.getTypeParameters(),
- classTree.getExtendsClause(),
- (List) classTree.getImplementsClause(),
- members);
+ TreeMaker make = wc.getTreeMaker();
+ ClassTree classTree = (ClassTree) classTreePath.getLeaf();
+ List members = new ArrayList<>(classTree.getMembers());
- wc.rewrite(classTree, newClassTree);
- }
- }
+ PropertyMethodBuilder propertyMethodBuilder = new PropertyMethodBuilder(make, fields);
- private List getFields(Lookup context, CompilationController controller) throws CodeGeneratorException {
- try {
- List elementList = new ArrayList<>();
- TreePath treePath = context.lookup(TreePath.class);
- TreePath path = TreeHelper.getParentElementOfKind(Tree.Kind.CLASS, treePath);
- TypeElement typeElement = (TypeElement) controller.getTrees().getElement(path);
+ List createdMethods = propertyMethodBuilder.createPropMethods();
- if (!typeElement.getKind().isClass()) {
- throw new CodeGeneratorException("typeElement " + typeElement.getKind().name() + " is not a class, cannot generate code.");
- }
+ /* Filtering out methods that might clash with the pre-existing ones. */
+ createdMethods.removeIf((MethodTree createdMethod) -> {
+ return TreeHelper.hasMethodWithSameName(members, createdMethod);
+ });
- Elements elements = controller.getElements();
- List temp = ElementFilter.fieldsIn(elements.getAllMembers(typeElement));
-
- for (VariableElement e : temp) {
- try {
- Class> memberClass = Class.forName(getClassName(e.asType().toString()));
- if (Property.class.isAssignableFrom(memberClass) &&
- !ListProperty.class.isAssignableFrom(memberClass) &&
- !MapProperty.class.isAssignableFrom(memberClass) &&
- !ObjectProperty.class.isAssignableFrom(memberClass) &&
- !SetProperty.class.isAssignableFrom(memberClass) ) {
-
- elementList.add(e);
- }
- } catch (Exception ex) {
- Exceptions.printStackTrace(ex);
- }
- }
- return elementList;
- } catch (NullPointerException ex) {
- throw new CodeGeneratorException(ex);
- }
- }
-
-
- protected String getClassName( String fullName ) {
- if( !fullName.contains("<") ) {
- return fullName;
- } else {
- return fullName.substring( 0, fullName.indexOf("<") );
- }
+ members.addAll(classMemberIndexAtCaret, createdMethods);
+
+ ClassTree newClassTree = make.Class(
+ classTree.getModifiers(),
+ classTree.getSimpleName(),
+ classTree.getTypeParameters(),
+ classTree.getExtendsClause(),
+ classTree.getImplementsClause(),
+ members);
+
+ wc.rewrite(classTree, newClassTree);
}
- private static class CodeGeneratorException extends Exception {
+ private static List getFields(CompilationController controller, TreePath classTreePath) {
+ Trees trees = controller.getTrees();
+ Elements elements = controller.getElements();
- private static final long serialVersionUID = 1L;
+ TypeElement typeElement = (TypeElement) trees.getElement(classTreePath);
- public CodeGeneratorException(String message) {
- super(message);
- }
+ List allFields = ElementFilter.fieldsIn(elements.getAllMembers(typeElement));
- public CodeGeneratorException(Throwable cause) {
- super(cause);
- }
- }
+ List supportedFields = allFields.stream().filter((VariableElement var) -> {
+ return SUPPORTED_CLASSES.contains(TypeHelper.getClassName(var.asType().toString()));
+ }).collect(Collectors.toList());
+ return supportedFields;
+ }
}
diff --git a/src/main/java/com/lynden/netbeans/javafx/PackageHelper.java b/src/main/java/com/lynden/netbeans/javafx/PackageHelper.java
deleted file mode 100644
index 566e9fe..0000000
--- a/src/main/java/com/lynden/netbeans/javafx/PackageHelper.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
-The MIT License (MIT)
-
-Copyright (c) 2015 Lynden, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-**/
-
-package com.lynden.netbeans.javafx;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Manipulates strings containing types.
- *
- */
-class PackageHelper {
-
- /** Removes packages from class names (it manages generics too).
- * i.e.
- * {@code java.lang.String -> String}
- * and
- * {@code java.util.List -> List}.
- */
- static String removePackagesFromGenericsType(String fullName) {
- final List list = new ArrayList<>();
- int idx = 0, counter = 0;
- for (char c : fullName.toCharArray()) {
- switch (c) {
- case ',':
- case '<':
- case '>':
- list.add(fullName.substring(idx, counter));
- list.add(String.valueOf(c));
- idx = counter + 1;
- break;
- }
- counter++;
- }
- if (list.isEmpty()) {
- return removePackageFromType(fullName);
- }
- StringBuilder buf = new StringBuilder();
- for (String s : list) {
- if ("<>,".contains(s)) {
- buf.append(s);
- } else {
- buf.append(removePackageFromType(s));
- }
- }
- return buf.toString();
- }
-
- /** Removes the package from a single class name (don't manage generics). */
- static String removePackageFromType(String fullname) {
- int lastIndexOfPoint = fullname.lastIndexOf('.');
- if (lastIndexOfPoint == -1) {
- return fullname;
- }
- return fullname.substring(lastIndexOfPoint + 1, fullname.length());
- }
-
-}
diff --git a/src/main/java/com/lynden/netbeans/javafx/PropertyMethodBuilder.java b/src/main/java/com/lynden/netbeans/javafx/PropertyMethodBuilder.java
index 1826d61..e93f54b 100644
--- a/src/main/java/com/lynden/netbeans/javafx/PropertyMethodBuilder.java
+++ b/src/main/java/com/lynden/netbeans/javafx/PropertyMethodBuilder.java
@@ -1,31 +1,33 @@
-/**
-The MIT License (MIT)
-
-Copyright (c) 2015 Lynden, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-**/
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Lynden, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
package com.lynden.netbeans.javafx;
-import com.sun.source.tree.AnnotationTree;
+import com.sun.source.tree.BlockTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.ModifiersTree;
+import com.sun.source.tree.StatementTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TypeParameterTree;
import com.sun.source.tree.VariableTree;
@@ -34,11 +36,10 @@ of this software and associated documentation files (the "Software"), to deal
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.VariableElement;
import org.netbeans.api.java.source.TreeMaker;
@@ -47,256 +48,282 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
public class PropertyMethodBuilder {
-
+
private static final String PROPERTY = "Property"; // NOI18N
- private static final Map PRIMITIVES_MAP;
+
+ private static final Map VALUE_TYPES = new HashMap<>();
+ private static final Map GENERIC_VALUE_TYPES = new HashMap<>();
+ private static final Set VALUE_TYPE_AS_PARAM = new HashSet<>();
+
+ private static final Set WRITABLE_PROPERTIES = new HashSet<>();
+ private static final Map WRAPPED_READ_ONLY_TYPES = new HashMap<>();
static {
- PRIMITIVES_MAP = new HashMap<>();
- PRIMITIVES_MAP.put("Integer", "int");
- PRIMITIVES_MAP.put("Float", "float");
- PRIMITIVES_MAP.put("Double", "double");
- PRIMITIVES_MAP.put("Boolean", "boolean");
- PRIMITIVES_MAP.put("Long", "long");
- }
- private static String replaceWithPrimitive(String typeName) {
- return PRIMITIVES_MAP.getOrDefault(typeName, typeName);
+ /* Type of the value can be found in map. */
+ VALUE_TYPES.put("javafx.beans.property.IntegerProperty", "int");
+ VALUE_TYPES.put("javafx.beans.property.LongProperty", "long");
+ VALUE_TYPES.put("javafx.beans.property.FloatProperty", "float");
+ VALUE_TYPES.put("javafx.beans.property.DoubleProperty", "double");
+ VALUE_TYPES.put("javafx.beans.property.BooleanProperty", "boolean");
+ VALUE_TYPES.put("javafx.beans.property.StringProperty", "java.lang.String");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyIntegerProperty", "int");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyLongProperty", "long");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyFloatProperty", "float");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyDoubleProperty", "double");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyBooleanProperty", "boolean");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyStringProperty", "java.lang.String");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyIntegerWrapper", "int");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyLongWrapper", "long");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyFloatWrapper", "float");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyDoubleWrapper", "double");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyBooleanWrapper", "boolean");
+ VALUE_TYPES.put("javafx.beans.property.ReadOnlyStringWrapper", "java.lang.String");
+
+ /* Type of the value can be found in map, but it requires the same type
+ * parameters as the property type. */
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.ListProperty", "javafx.collections.ObservableList");
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.SetProperty", "javafx.collections.ObservableSet");
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.MapProperty", "javafx.collections.ObservableMap");
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.ReadOnlyListProperty", "javafx.collections.ObservableList");
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.ReadOnlySetProperty", "javafx.collections.ObservableSet");
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.ReadOnlyMapProperty", "javafx.collections.ObservableMap");
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.ReadOnlyListWrapper", "javafx.collections.ObservableList");
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.ReadOnlySetWrapper", "javafx.collections.ObservableSet");
+ GENERIC_VALUE_TYPES.put("javafx.beans.property.ReadOnlyMapWrapper", "javafx.collections.ObservableMap");
+
+ /* Type of the value is given as a type parameter of the property type. */
+ VALUE_TYPE_AS_PARAM.add("javafx.beans.property.ObjectProperty");
+ VALUE_TYPE_AS_PARAM.add("javafx.beans.property.ReadOnlyObjectProperty");
+ VALUE_TYPE_AS_PARAM.add("javafx.beans.property.ReadOnlyObjectWrapper");
+
+
+ /* These property types are writable. */
+ WRITABLE_PROPERTIES.add("javafx.beans.property.IntegerProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.LongProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.FloatProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.DoubleProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.BooleanProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.StringProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.ListProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.SetProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.MapProperty");
+ WRITABLE_PROPERTIES.add("javafx.beans.property.ObjectProperty");
+
+ /* Read-only wrapper types and their respective wrapped types. These may
+ * or may not be generic. If they are, the type parameters are the same. */
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyIntegerWrapper", "javafx.beans.property.ReadOnlyIntegerProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyLongWrapper", "javafx.beans.property.ReadOnlyLongProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyFloatWrapper", "javafx.beans.property.ReadOnlyFloatProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyDoubleWrapper", "javafx.beans.property.ReadOnlyDoubleProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyBooleanWrapper", "javafx.beans.property.ReadOnlyBooleanProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyStringWrapper", "javafx.beans.property.ReadOnlyStringProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyListWrapper", "javafx.beans.property.ReadOnlyListProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlySetWrapper", "javafx.beans.property.ReadOnlySetProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyMapWrapper", "javafx.beans.property.ReadOnlyMapProperty");
+ WRAPPED_READ_ONLY_TYPES.put("javafx.beans.property.ReadOnlyObjectWrapper", "javafx.beans.property.ReadOnlyObjectProperty");
}
- private final TreeMaker make;
- private final List members;
- private final List elements;
- private final String className;
+ private static String getValueType(String typeName) {
-
+ String className = TypeHelper.getClassName(typeName);
+ String typeParams = TypeHelper.getTypeParameters(typeName);
- public PropertyMethodBuilder(TreeMaker make,
- List members,
- List elements,
- String className) {
- this.make = make;
- this.members = members;
- this.elements = elements;
- this.className = className;
- }
+ if (VALUE_TYPES.containsKey(className)) {
+ return VALUE_TYPES.get(className);
+
+ } else if (GENERIC_VALUE_TYPES.containsKey(className)) {
+ return GENERIC_VALUE_TYPES.get(className) + '<' + typeParams + '>';
- int removeExistingPropMethods(int index) {
- int counter = 0;
- if( elements == null ) {
- return 0;
+ } else if (VALUE_TYPE_AS_PARAM.contains(className)) {
+ return typeParams;
+
+ } else {
+ return "java.lang.Object";
}
- for (Iterator treeIt = members.iterator(); treeIt.hasNext();) {
- Tree member = treeIt.next();
-
- if (member.getKind().equals(Tree.Kind.METHOD)) {
- MethodTree mt = (MethodTree) member;
- for (Element element : elements) {
- if( mt.getName().contentEquals(getGetterName(element.getSimpleName().toString()) ) ||
- mt.getName().contentEquals(getGetterName(element.getSimpleName().toString(), "is") ) ||
-
- mt.getName().contentEquals(getSetterName(element.getSimpleName().toString()) ) ||
- mt.getName().contentEquals(getPropertyMethodName(element.getSimpleName().toString()))) {
-
- treeIt.remove();
- if (index > counter) {
- index--;
- }
- break;
- }
- }
- }
- counter++;
+ }
+
+ private static boolean isWritableType(String typeName) {
+ return WRITABLE_PROPERTIES.contains(TypeHelper.getClassName(typeName));
+ }
+
+ private static boolean isWrapperType(String typeName) {
+ return WRAPPED_READ_ONLY_TYPES.containsKey(TypeHelper.getClassName(typeName));
+ }
+
+ private static String getWrappedReadOnlyType(String typeName) {
+
+ String className = TypeHelper.getClassName(typeName);
+ String typeParams = TypeHelper.getTypeParameters(typeName);
+
+ if (typeParams == null) {
+ return WRAPPED_READ_ONLY_TYPES.get(className);
+ } else {
+ return WRAPPED_READ_ONLY_TYPES.get(className) + '<' + typeParams + '>';
}
- return index;
}
- void addPropMethods(int index) {
+ private final TreeMaker make;
+ private final List fields;
+
+ public PropertyMethodBuilder(TreeMaker make, List fields) {
+ this.make = make;
+ this.fields = fields;
+ }
+
+ List createPropMethods() {
- if( elements == null ) {
- return;
+ if (fields == null) {
+ return Collections.emptyList();
}
-
- int position = index - 1;
- for (VariableElement element : elements) {
- position = Math.min(position + 1, members.size());
- members.add(position, createSetMethod(element));
- position = Math.min(position + 1, members.size());
- members.add(position, createGetMethod(element));
- position = Math.min(position + 1, members.size());
- members.add(position, createPropertyMethod(element));
+ List createdMethods = new ArrayList<>();
+ for (VariableElement field : fields) {
+
+ createdMethods.add(createGetMethod(field));
+
+ /* Only create set method if property is writable */
+ if (isWritableType(field.asType().toString())) {
+ createdMethods.add(createSetMethod(field));
+ }
+
+ createdMethods.add(createPropertyMethod(field));
}
+ return createdMethods;
}
- protected MethodTree createGetMethod(VariableElement element) {
- Set modifiers = EnumSet.of(Modifier.PUBLIC, Modifier.FINAL);
- List annotations = new ArrayList<>();
- String typeName = replaceWithPrimitive(toStringWithoutPackages(element));
- VariableTree parameter = make.Variable(make.Modifiers(new HashSet(), Collections.emptyList()), "value", make.Identifier(typeName),
- null);
+ protected MethodTree createGetMethod(VariableElement field) {
+ ModifiersTree modifiers = make.Modifiers(EnumSet.of(Modifier.PUBLIC, Modifier.FINAL));
+
+ String returnTypeName = getValueType(field.asType().toString());
+ Tree returnType = make.Type(returnTypeName);
- ExpressionTree returnType = make.QualIdent(parameter.getType().toString());
+ String getterPrefix = ("boolean".equals(returnTypeName)) ? "is" : "get";
+ String name = getGetMethodName(field.getSimpleName().toString(), getterPrefix);
- final String bodyText = createPropGetterMethodBody(element);
+ List typeParameters = Collections.emptyList();
- String setterPrefix = ("boolean".equals(typeName)) ? "is" : "get";
+ List parameters = Collections.emptyList();
- MethodTree method = make.Method(
- make.Modifiers(modifiers, annotations),
- getGetterName(element.getSimpleName().toString(), setterPrefix),
- returnType,
- Collections.emptyList(),
- //Collections.singletonList(parameter),
- Collections.emptyList(),
- Collections.emptyList(),
- bodyText,
- null);
+ List throwsList = Collections.emptyList();
- return method;
+ BlockTree body = createGetMethodBody(field);
+ ExpressionTree defaultValue = null;
+
+
+ return make.Method(modifiers, name, returnType, typeParameters, parameters, throwsList, body, defaultValue);
}
- protected MethodTree createPropertyMethod(VariableElement element) {
- Set modifiers = EnumSet.of(Modifier.PUBLIC, Modifier.FINAL);
- List annotations = new ArrayList<>();
- VariableTree parameter = make.Variable(make.Modifiers(new HashSet(), Collections.emptyList()), "value", make.Identifier(toStringWithoutPackages(element)),
- null);
+ protected MethodTree createSetMethod(VariableElement field) {
+ ModifiersTree modifiers = make.Modifiers(EnumSet.of(Modifier.PUBLIC, Modifier.FINAL));
+
+ Tree returnType = make.Type("void");
+
+ String name = getSetMethodName(field.getSimpleName().toString());
- ExpressionTree returnType = make.QualIdent(parameter.getType().toString() + PROPERTY);
+ List typeParameters = Collections.emptyList();
- final String bodyText = createPropertyMethodBody(element);
+ String parameterTypeName = getValueType(field.asType().toString());
+ String parameterName = "value";
+ VariableTree parameter = make.Variable(make.Modifiers(Collections.emptySet()), parameterName, make.Type(parameterTypeName), null);
+ List parameters = Collections.singletonList(parameter);
- MethodTree method = make.Method(
- make.Modifiers(modifiers, annotations),
- getPropertyMethodName(element.getSimpleName().toString()),
- returnType,
- Collections.emptyList(),
- //Collections.singletonList(parameter),
- Collections.emptyList(),
- Collections.emptyList(),
- bodyText,
- null);
+ List throwsList = Collections.emptyList();
- return method;
+ BlockTree body = createSetMethodBody(field, parameterName);
+ ExpressionTree defaultValue = null;
+
+
+ return make.Method(modifiers, name, returnType, typeParameters, parameters, throwsList, body, defaultValue);
}
- protected MethodTree createSetMethod(VariableElement element) {
- Set modifiers = EnumSet.of(Modifier.PUBLIC, Modifier.FINAL);
- List annotations = new ArrayList<>();
- String typeName = replaceWithPrimitive(toStringWithoutPackages(element));
- VariableTree parameter = make.Variable(make.Modifiers(new HashSet(), Collections.emptyList()), "value", make.Identifier(typeName),
- null);
+ protected MethodTree createPropertyMethod(VariableElement field) {
+ ModifiersTree modifiers = make.Modifiers(EnumSet.of(Modifier.PUBLIC));
- ExpressionTree returnType = make.QualIdent("void");
+ String fieldTypeName = field.asType().toString();
+ boolean isReadOnlyWrapper = isWrapperType(fieldTypeName);
- final String bodyText = createPropSetterMethodBody(element);
+ Tree returnType = make.Type(isReadOnlyWrapper ? getWrappedReadOnlyType(fieldTypeName) : fieldTypeName);
- MethodTree method = make.Method(
- make.Modifiers(modifiers, annotations),
- getSetterName(element.getSimpleName().toString()),
- returnType,
- Collections.emptyList(),
- //Collections.singletonList(parameter),
- Collections.singletonList(parameter),
- Collections.emptyList(),
- bodyText,
- null);
+ String name = getPropertyMethodName(field.getSimpleName().toString());
- return method;
+ List typeParameters = Collections.emptyList();
- }
+ List parameters = Collections.emptyList();
- protected String createPropertyMethodBody(Element element) {
- StringBuilder sb = new StringBuilder();
- sb.append("{\n")
- .append("return ")
- .append(element.getSimpleName())
- .append(";\n}");
- return sb.toString();
+ List throwsList = Collections.emptyList();
+
+ BlockTree body = createPropertyMethodBody(field, isReadOnlyWrapper);
+
+ ExpressionTree defaultValue = null;
+
+
+ return make.Method(modifiers, name, returnType, typeParameters, parameters, throwsList, body, defaultValue);
}
- protected String createPropGetterMethodBody(Element element) {
- StringBuilder sb = new StringBuilder();
- sb.append("{\n")
- .append("return ")
- .append(element.getSimpleName())
- .append(".get();\n}");
- return sb.toString();
+ protected BlockTree createGetMethodBody(VariableElement field) {
+ /* return field.get(); */
+ ExpressionTree method = make.MemberSelect(make.Identifier(field), "get");
+ StatementTree statement = make.Return(make.MethodInvocation(Collections.emptyList(), method, Collections.emptyList()));
+
+ return make.Block(Collections.singletonList(statement), false);
}
- protected String createPropSetterMethodBody(Element element) {
- StringBuilder sb = new StringBuilder();
- sb.append("{\n")
- .append(element.getSimpleName())
- .append(".set(value);\n}");
- return sb.toString();
+ protected BlockTree createSetMethodBody(VariableElement field, String parameterName) {
+ /* field.set(parameterName); */
+ ExpressionTree method = make.MemberSelect(make.Identifier(field), "set");
+ ExpressionTree parameter = make.Identifier(parameterName);
+ StatementTree statement = make.ExpressionStatement(make.MethodInvocation(Collections.emptyList(), method, Collections.singletonList(parameter)));
+
+ return make.Block(Collections.singletonList(statement), false);
}
- void addFields() {
- for (VariableElement element : elements) {
- VariableTree field
- = make.Variable(make.Modifiers(
- EnumSet.of(Modifier.PRIVATE),
- Collections.emptyList()),
- element.getSimpleName().toString(),
- make.Identifier(toStringWithoutPackages(element)),
- null);
-
- members.add(field);
+ protected BlockTree createPropertyMethodBody(VariableElement field, boolean isReadOnlyWrapper) {
+ StatementTree statement;
+ if (isReadOnlyWrapper) {
+ /* return field.getReadOnlyProperty(); */
+ ExpressionTree method = make.MemberSelect(make.Identifier(field), "getReadOnlyProperty");
+ statement = make.Return(make.MethodInvocation(Collections.emptyList(), method, Collections.emptyList()));
+ } else {
+ /* return field; */
+ statement = make.Return(make.Identifier(field));
}
+
+ return make.Block(Collections.singletonList(statement), false);
}
- private String getPropertyMethodName(String fieldName) {
- final StringBuilder sb = new StringBuilder();
- sb.append(this.prepareFieldNameForMethodName(fieldName, Boolean.FALSE));
- sb.append(PROPERTY);
-
- return sb.toString();
+ private static String getGetMethodName(String fieldName) {
+ return getGetMethodName(fieldName, "get");
}
- private String getSetterName(String fieldName) {
- final StringBuilder sb = new StringBuilder();
- sb.append("set");
- sb.append(this.prepareFieldNameForMethodName(fieldName));
-
- return sb.toString();
+ private static String getGetMethodName(String fieldName, String prefix) {
+ return prefix + prepareFieldNameForMethodName(fieldName);
}
- private String getGetterName(String fieldName) {
- return getGetterName(fieldName, "get");
+ private static String getSetMethodName(String fieldName) {
+ return "set" + prepareFieldNameForMethodName(fieldName);
}
- private String getGetterName(String fieldName, String prefix) {
- final StringBuilder sb = new StringBuilder();
- sb.append(prefix);
- sb.append(this.prepareFieldNameForMethodName(fieldName));
-
- return sb.toString();
+ private static String getPropertyMethodName(String fieldName) {
+ return prepareFieldNameForMethodName(fieldName, false) + PROPERTY;
}
-
- private String prepareFieldNameForMethodName(String fieldName, boolean firstCharToUpperCase) {
+
+ private static String prepareFieldNameForMethodName(String fieldName, boolean firstCharToUpperCase) {
if (firstCharToUpperCase) {
- fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+ fieldName = fieldName.substring(0, 1).toUpperCase(Locale.ROOT) + fieldName.substring(1);
}
-
+
if (fieldName.endsWith(PROPERTY)) {
fieldName = fieldName.substring(0, fieldName.length() - PROPERTY.length());
}
-
+
return fieldName;
}
-
- private String prepareFieldNameForMethodName(String fieldName) {
- return this.prepareFieldNameForMethodName(fieldName, Boolean.TRUE);
- }
-
- private static String toStringWithoutPackages(VariableElement element) {
- String fullProp = PackageHelper.removePackagesFromGenericsType(element.asType().toString());
- return fullProp.substring(0, fullProp.indexOf(("Prop")));
+ private static String prepareFieldNameForMethodName(String fieldName) {
+ return prepareFieldNameForMethodName(fieldName, true);
}
-
}
diff --git a/src/main/java/com/lynden/netbeans/javafx/TreeHelper.java b/src/main/java/com/lynden/netbeans/javafx/TreeHelper.java
index dbaecb4..0d252e9 100644
--- a/src/main/java/com/lynden/netbeans/javafx/TreeHelper.java
+++ b/src/main/java/com/lynden/netbeans/javafx/TreeHelper.java
@@ -1,34 +1,34 @@
-/**
-The MIT License (MIT)
-
-Copyright (c) 2015 Lynden, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-**/
-
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Lynden, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
package com.lynden.netbeans.javafx;
import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
import java.io.IOException;
+import java.util.Collection;
import javax.swing.text.Document;
import org.netbeans.api.java.source.WorkingCopy;
import org.netbeans.editor.GuardedDocument;
@@ -37,25 +37,6 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
class TreeHelper {
- /**
- * Search up the hierarchy of elements for one of the given kind.
- *
- * @param kind the element's kind to search for
- * @param path the starting element
- * @return {@code null} if no element was found.
- */
- static TreePath getParentElementOfKind(Tree.Kind kind, TreePath path) {
- if (path != null) {
- TreePath tpath = path;
- while (tpath != null) {
- if (kind == tpath.getLeaf().getKind()) {
- return tpath;
- }
- tpath = tpath.getParentPath();
- }
- }
- return null;
- }
/**
* Find the index of the current class member.
@@ -100,4 +81,17 @@ static int findClassMemberIndex(WorkingCopy wc,
return index;
}
+ /**
+ * Checks if the given collection of {@code members} contains a method with
+ * the same name as the given {@code method}.
+ *
+ * @param members
+ * @param method
+ * @return true if the collection contains a method with the same name
+ */
+ static boolean hasMethodWithSameName(Collection members, MethodTree method) {
+ return members.stream().anyMatch((Tree member) -> {
+ return member.getKind().equals(Tree.Kind.METHOD) && ((MethodTree) member).getName().contentEquals(method.getName());
+ });
+ }
}
diff --git a/src/main/java/com/lynden/netbeans/javafx/TypeHelper.java b/src/main/java/com/lynden/netbeans/javafx/TypeHelper.java
new file mode 100644
index 0000000..3dd43d2
--- /dev/null
+++ b/src/main/java/com/lynden/netbeans/javafx/TypeHelper.java
@@ -0,0 +1,63 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Lynden, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lynden.netbeans.javafx;
+
+/**
+ * Manipulates strings containing types.
+ *
+ */
+class TypeHelper {
+
+ /**
+ * Returns only the class name part of a type name without type parameters.
+ * {@code "java.util.Map" -> "java.util.Map"}
+ *
+ * @param fullName
+ * @return class name
+ */
+ static String getClassName(String fullName) {
+ if (!fullName.contains("<")) {
+ return fullName;
+ } else {
+ return fullName.substring(0, fullName.indexOf('<'));
+ }
+ }
+
+ /**
+ * Returns only the type parameters part of a type name. Type params are in
+ * the same form as in the original type. If there were no type parameters,
+ * null is returned.
+ * {@code "java.util.Map" -> "java.lang.String, java.lang.String"}
+ *
+ * @param fullName
+ * @return type parameters
+ */
+ static String getTypeParameters(String fullName) {
+ if (!fullName.contains("<")) {
+ return null;
+ } else {
+ return fullName.substring(fullName.indexOf('<') + 1, fullName.lastIndexOf('>'));
+ }
+ }
+}
diff --git a/src/main/resources/com/lynden/netbeans/javafx/Bundle.properties b/src/main/resources/com/lynden/netbeans/javafx/Bundle.properties
index 311c424..8b4629e 100644
--- a/src/main/resources/com/lynden/netbeans/javafx/Bundle.properties
+++ b/src/main/resources/com/lynden/netbeans/javafx/Bundle.properties
@@ -2,5 +2,5 @@
OpenIDE-Module-Name=JavaFx Property Getter & Setter Generator
OpenIDE-Module-Short-Description=Automatically generates getter and setter methods for JavaFx Properties in a POJO.
OpenIDE-Module-Long-Description=Automatically generates getter and setter methods for JavaFx Properties in a POJO.
-OpenIDE-Module-Display-Category=JavaFx
+OpenIDE-Module-Display-Category=JavaFX 2
#Tue Sep 29 14:37:09 PDT 2015