### Eclipse Workspace Patch 1.0
#P org.eclipse.jdt.ui.tests
Index: ui/org/eclipse/jdt/ui/tests/core/source/GenerateToStringTest.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/GenerateToStringTest.java,v
retrieving revision 1.1
diff -u -r1.1 GenerateToStringTest.java
--- ui/org/eclipse/jdt/ui/tests/core/source/GenerateToStringTest.java 9 Mar 2009 19:20:21 -0000 1.1
+++ ui/org/eclipse/jdt/ui/tests/core/source/GenerateToStringTest.java 17 Apr 2009 14:18:12 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
+ * Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
*******************************************************************************/
package org.eclipse.jdt.ui.tests.core.source;
@@ -22,6 +23,7 @@
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
@@ -33,6 +35,7 @@
import org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.GenerateToStringOperation;
import org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringGenerationSettings;
import org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringTemplateParser;
+import org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringGenerationSettings.CustomBuilderSettings;
import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
@@ -71,6 +74,26 @@
fSettings2.useBlocks= true;
fSettings2.is50orHigher= true;
fSettings2.is60orHigher= true;
+ fSettings2.customBuilderSettings= new CustomBuilderSettings();
+ fSettings2.customBuilderSettings.className= "com.pack.ToStringBuilder";
+ fSettings2.customBuilderSettings.label= "builder";
+ fSettings2.customBuilderSettings.appendMethod= "append";
+ fSettings2.customBuilderSettings.resultMethod= "toString";
+ fSettings2.customBuilderSettings.chainCalls= false;
+
+ IPackageFragment packageFragment= fRoot.createPackageFragment("com.pack", true, null);
+ ICompilationUnit compilationUnit= packageFragment.getCompilationUnit("ToStringBuilder.java");
+ compilationUnit
+ .createType(
+ "package com.pack;\npublic class ToStringBuilder {\npublic ToStringBuilder(Object o){\n}\npublic ToStringBuilder append(String s, Object o){\nreturn null;\n}\npublic String toString(){\nreturn null;\n}\n}\n",
+ null, true, null);
+
+ packageFragment= fRoot.createPackageFragment("org.another.pack", true, null);
+ compilationUnit= packageFragment.getCompilationUnit("AnotherToStringCreator.java");
+ compilationUnit
+ .createType(
+ "package org.another.pack;\npublic class AnotherToStringCreator {\npublic AnotherToStringCreator(java.lang.Object o) {\n}\npublic AnotherToStringCreator addSth(Object o, String s) {\n return null;\n}\npublic String addSth(String s, int i){\nreturn null;\n}\npublic void addSth(boolean b, String s){\n}\npublic String getResult(){\nreturn null;\n}\n}\n",
+ null, true, null);
}
public void runOperation(IType type, IMember[] members, IJavaElement insertBefore) throws CoreException {
@@ -2136,11 +2159,11 @@
}
/**
- * Apache ToStringbuilder - basic case
+ * Custom ToString() builder - basic case
*
* @throws Exception
*/
- public void testApacheBuilder() throws Exception {
+ public void testCustomBuilder() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
@@ -2150,7 +2173,7 @@
fSettings2.toStringStyle= 4;
runOperation(a.getType("A"), members, null);
- String expected= "package p;\r\n" + "\r\n" + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
+ String expected= "package p;\r\n" + "\r\n" + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
+ " int anInt;\r\n" + " String aString;\r\n" + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n"
+ " }\r\n" + " int[] anArrayMethod() {\r\n" + " return new int[0];\r\n" + " }\r\n" + " @Override\r\n" + " public String toString() {\r\n"
+ " ToStringBuilder builder = new ToStringBuilder(this);\r\n" + " builder.append(\"aStringMethod()\", aStringMethod());\r\n"
@@ -2161,11 +2184,11 @@
}
/**
- * Apache ToStringbuilder - skip nulls
+ * Custom ToString() builder - skip nulls
*
* @throws Exception
*/
- public void testApacheBuilderNulls() throws Exception {
+ public void testCustomBuilderNulls() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
@@ -2176,7 +2199,7 @@
fSettings2.toStringStyle= 4;
runOperation(a.getType("A"), members, null);
- String expected= "package p;\r\n" + "\r\n" + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
+ String expected= "package p;\r\n" + "\r\n" + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
+ " int anInt;\r\n" + " String aString;\r\n" + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n"
+ " }\r\n" + " int[] anArrayMethod() {\r\n" + " return new int[0];\r\n" + " }\r\n" + " @Override\r\n" + " public String toString() {\r\n"
+ " ToStringBuilder builder = new ToStringBuilder(this);\r\n" + " if (aStringMethod() != null) {\r\n" + " builder.append(\"aStringMethod()\", aStringMethod());\r\n" + " }\r\n"
@@ -2188,11 +2211,11 @@
}
/**
- * Apache ToStringbuilder - custom array toString without limit of elements
+ * Custom ToString() builder - custom array toString without limit of elements
*
* @throws Exception
*/
- public void testApacheBuilderArray() throws Exception {
+ public void testCustomBuilderArray() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n"
+ " int[] intArray;\r\n" + " float[] floatArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " char[] anArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n"
+ " java.util.List list;\r\n" + "\r\n" + "}\r\n" + "", true, null);
@@ -2202,7 +2225,7 @@
fSettings2.toStringStyle= 4;
runOperation(a.getType("A"), members, null);
- String expected= "package p;\r\n" + "\r\n" + "import java.util.Arrays;\r\n" + "\r\n" + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n"
+ String expected= "package p;\r\n" + "\r\n" + "import java.util.Arrays;\r\n" + "\r\n" + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n"
+ " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n" + " int[] intArray;\r\n" + " float[] floatArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n"
+ " char[] anArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n" + " java.util.List list;\r\n" + " @Override\r\n" + " public String toString() {\r\n"
+ " ToStringBuilder builder = new ToStringBuilder(this);\r\n" + " builder.append(\"AArray\", Arrays.toString(AArray));\r\n" + " builder.append(\"aBool\", aBool);\r\n"
@@ -2214,11 +2237,11 @@
}
/**
- * Apache ToStringbuilder - limit of elements but not arrays
+ * Custom ToString() builder - limit of elements but not arrays
*
* @throws Exception
*/
- public void testApacheBuilderLimit() throws Exception {
+ public void testCustomBuilderLimit() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.List;\r\n"
+ "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n" + " int[] intArray;\r\n" + " float[] floatArray;\r\n"
+ " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " char[] charArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n" + " float[] floatArrayMethod() {\r\n"
@@ -2232,7 +2255,7 @@
runOperation(a.getType("A"), members, null);
String expected= "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.Iterator;\r\n" + "import java.util.List;\r\n" + "\r\n"
- + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n"
+ + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n"
+ " int[] intArray;\r\n" + " float[] floatArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " char[] charArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n"
+ " float[] floatArrayMethod() {\r\n" + " return null;\r\n" + " }\r\n" + " List list;\r\n" + " HashMap hashMap;\r\n" + " Collection> wildCollection;\r\n"
+ " Collection integerCollection;\r\n" + " @Override\r\n" + " public String toString() {\r\n" + " final int maxLen = 10;\r\n"
@@ -2252,11 +2275,11 @@
/**
- * Apache ToStringbuilder - custom array toString and limit of elements
+ * Custom ToString() builder - custom array toString and limit of elements
*
* @throws Exception
*/
- public void testApacheBuilderArrayLimit() throws Exception {
+ public void testCustomBuilderArrayLimit() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.List;\r\n"
+ "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n" + " int[] intArray;\r\n" + " float[] floatArray;\r\n"
+ " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " char[] charArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n" + " float[] floatArrayMethod() {\r\n"
@@ -2271,7 +2294,7 @@
runOperation(a.getType("A"), members, null);
String expected= "package p;\r\n" + "\r\n" + "import java.util.Arrays;\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.Iterator;\r\n"
- + "import java.util.List;\r\n" + "\r\n" + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n"
+ + "import java.util.List;\r\n" + "\r\n" + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n"
+ " Object object;\r\n" + " A anA;\r\n" + " int[] intArray;\r\n" + " float[] floatArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " char[] charArrayMethod() {\r\n"
+ " return new char[0];\r\n" + " }\r\n" + " float[] floatArrayMethod() {\r\n" + " return null;\r\n" + " }\r\n" + " List list;\r\n"
+ " HashMap hashMap;\r\n" + " Collection> wildCollection;\r\n" + " Collection integerCollection;\r\n" + " @Override\r\n"
@@ -2296,11 +2319,11 @@
}
/**
- * Apache ToStringbuilder - custom array toString and limit of elements, unique names needed
+ * Custom ToString() builder - custom array toString and limit of elements, unique names needed
*
* @throws Exception
*/
- public void testApacheBuilderArrayLimitUnique() throws Exception {
+ public void testCustomBuilderArrayLimitUnique() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.List;\r\n"
+ "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " int[] intArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " List list;\r\n"
+ " HashMap hashMap;\r\n" + " Collection wildCollection;\r\n" + " Collection integerCollection;\r\n" + " Object builder;\r\n" + " Object buffer;\r\n" + " Object maxLen;\r\n"
@@ -2314,7 +2337,7 @@
runOperation(a.getType("A"), members, null);
String expected= "package p;\r\n" + "\r\n" + "import java.util.Arrays;\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.Iterator;\r\n"
- + "import java.util.List;\r\n" + "\r\n" + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n"
+ + "import java.util.List;\r\n" + "\r\n" + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n"
+ " int[] intArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " List list;\r\n" + " HashMap hashMap;\r\n" + " Collection wildCollection;\r\n"
+ " Collection integerCollection;\r\n" + " Object builder;\r\n" + " Object buffer;\r\n" + " Object maxLen;\r\n" + " Object len;\r\n" + " Object collection;\r\n" + " Object array;\r\n"
+ " @Override\r\n" + " public String toString() {\r\n" + " final int maxLen2 = 10;\r\n" + " ToStringBuilder builder2 = new ToStringBuilder(this);\r\n"
@@ -2337,11 +2360,11 @@
}
/**
- * Apache ToStringbuilder - skip nulls, use keyword this, no one-line blocks
+ * Custom ToString() builder - skip nulls, use keyword this, no one-line blocks
*
* @throws Exception
*/
- public void testApacheBuilderNullsThisNoBlocks() throws Exception {
+ public void testCustomBuilderNullsThisNoBlocks() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.List;\r\n"
+ "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n" + " int[] intArray;\r\n" + " float[] floatArray;\r\n"
+ " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " char[] charArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n" + " float[] floatArrayMethod() {\r\n"
@@ -2358,7 +2381,7 @@
runOperation(a.getType("A"), members, null);
String expected= "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.List;\r\n" + "\r\n"
- + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n"
+ + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " Object object;\r\n" + " A anA;\r\n"
+ " int[] intArray;\r\n" + " float[] floatArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " char[] charArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n"
+ " float[] floatArrayMethod() {\r\n" + " return null;\r\n" + " }\r\n" + " List list;\r\n" + " HashMap hashMap;\r\n" + " Collection> wildCollection;\r\n"
+ " Collection integerCollection;\r\n" + " @Override\r\n" + " public String toString() {\r\n" + " ToStringBuilder builder = new ToStringBuilder(this);\r\n"
@@ -2375,11 +2398,11 @@
}
/**
- * Apache ToStringbuilder - custom array, limit elements, skip nulls
+ * Custom ToString() builder - custom array, limit elements, skip nulls
*
* @throws Exception
*/
- public void testApacheBuilderArrayLimitNulls() throws Exception {
+ public void testCustomBuilderArrayLimitNulls() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.List;\r\n"
+ "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " Object object;\r\n" + " A anA;\r\n" + " int[] intArray;\r\n" + " float[] floatArray;\r\n"
+ " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " char[] charArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n" + " float[] floatArrayMethod() {\r\n"
@@ -2396,7 +2419,7 @@
runOperation(a.getType("A"), members, null);
String expected= "package p;\r\n" + "\r\n" + "import java.util.Arrays;\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.Iterator;\r\n"
- + "import java.util.List;\r\n" + "\r\n" + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n"
+ + "import java.util.List;\r\n" + "\r\n" + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n"
+ " int anInt;\r\n" + " Object object;\r\n" + " A anA;\r\n" + " int[] intArray;\r\n" + " float[] floatArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n"
+ " char[] charArrayMethod() {\r\n" + " return new char[0];\r\n" + " }\r\n" + " float[] floatArrayMethod() {\r\n" + " return null;\r\n" + " }\r\n" + " List list;\r\n"
+ " HashMap hashMap;\r\n" + " Collection> wildCollection;\r\n" + " Collection integerCollection;\r\n" + " @Override\r\n"
@@ -2422,23 +2445,24 @@
}
/**
- * Apache ToStringbuilder, chained calls - basic case
+ * Custom ToString() builder - chained calls
*
* @throws Exception
*/
- public void testChainedApacheBuilder() throws Exception {
+ public void testChainedCustomBuilder() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
+ " return new int[0];\r\n" + " }\r\n" + "\r\n" + "}", true, null);
IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "aFloatMethod", "anArrayMethod", "aBool", "aString", "anInt" });
- fSettings2.toStringStyle= 5;
+ fSettings2.toStringStyle= 4;
+ fSettings2.customBuilderSettings.chainCalls= true;
runOperation(a.getType("A"), members, null);
String expected= "package p;\r\n"
+ "\r\n"
- + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n"
+ + "import com.pack.ToStringBuilder;\r\n"
+ "\r\n"
+ "public class A {\r\n"
+ " \r\n"
@@ -2465,11 +2489,11 @@
}
/**
- * Apache ToStringbuilder, chained calls - skip nulls
+ * Custom ToString() builder - chained calls, skip nulls
*
* @throws Exception
*/
- public void testChainedApacheBuilderNulls() throws Exception {
+ public void testChainedCustomBuilderNulls() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
@@ -2477,10 +2501,11 @@
IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "aFloatMethod", "anArrayMethod", "aString", "aBool", "anInt" });
fSettings2.skipNulls= true;
- fSettings2.toStringStyle= 5;
+ fSettings2.toStringStyle= 4;
+ fSettings2.customBuilderSettings.chainCalls= true;
runOperation(a.getType("A"), members, null);
- String expected= "package p;\r\n" + "\r\n" + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
+ String expected= "package p;\r\n" + "\r\n" + "import com.pack.ToStringBuilder;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
+ " int anInt;\r\n" + " String aString;\r\n" + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n"
+ " }\r\n" + " int[] anArrayMethod() {\r\n" + " return new int[0];\r\n" + " }\r\n" + " @Override\r\n" + " public String toString() {\r\n"
+ " ToStringBuilder builder = new ToStringBuilder(this);\r\n" + " if (aStringMethod() != null) {\r\n" + " builder.append(\"aStringMethod()\", aStringMethod());\r\n" + " }\r\n"
@@ -2492,11 +2517,11 @@
}
/**
- * Apache ToStringbuilder, chained calls - add comment
+ * Custom ToString() builder - chained calls, add comment
*
* @throws Exception
*/
- public void testChainedApacheBuilderComments() throws Exception {
+ public void testChainedCustomBuilderComments() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
@@ -2504,12 +2529,13 @@
IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "aFloatMethod", "anArrayMethod", "aString", "aBool", "anInt" });
fSettings2.createComments= true;
- fSettings2.toStringStyle= 5;
+ fSettings2.toStringStyle= 4;
+ fSettings2.customBuilderSettings.chainCalls= true;
runOperation(a.getType("A"), members, null);
String expected= "package p;\r\n"
+ "\r\n"
- + "import org.apache.commons.lang.builder.ToStringBuilder;\r\n"
+ + "import com.pack.ToStringBuilder;\r\n"
+ "\r\n"
+ "public class A {\r\n"
+ " \r\n"
@@ -2539,36 +2565,66 @@
}
/**
- * Spring ToStringCreator - basic case
+ * Custom toString() builder - alternative class, basic case
*
* @throws Exception
*/
- public void testSpringCreator() throws Exception {
+ public void testAlternativeCustomBuilder() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
+ " return new int[0];\r\n" + " }\r\n" + "\r\n" + "}", true, null);
IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "aFloatMethod", "anArrayMethod", "aBool", "aString", "anInt" });
- fSettings2.toStringStyle= 6;
+ fSettings2.toStringStyle= 4;
+ fSettings2.customBuilderSettings.className= "org.another.pack.AnotherToStringCreator";
+ fSettings2.customBuilderSettings.label= "creator";
+ fSettings2.customBuilderSettings.appendMethod= "addSth";
+ fSettings2.customBuilderSettings.resultMethod= "getResult";
runOperation(a.getType("A"), members, null);
- String expected= "package p;\r\n" + "\r\n" + "import org.springframework.core.style.ToStringCreator;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
- + " int anInt;\r\n" + " String aString;\r\n" + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n"
- + " }\r\n" + " int[] anArrayMethod() {\r\n" + " return new int[0];\r\n" + " }\r\n" + " @Override\r\n" + " public String toString() {\r\n"
- + " ToStringCreator creator = new ToStringCreator(this);\r\n" + " creator.append(\"aStringMethod()\", aStringMethod());\r\n"
- + " creator.append(\"aFloatMethod()\", aFloatMethod());\r\n" + " creator.append(\"anArrayMethod()\", anArrayMethod());\r\n" + " creator.append(\"aBool\", aBool);\r\n"
- + " creator.append(\"aString\", aString);\r\n" + " creator.append(\"anInt\", anInt);\r\n" + " return creator.toString();\r\n" + " }\r\n" + "\r\n" + "}";
+ String expected= "package p;\r\n"
+ + "\r\n"
+ + "import org.another.pack.AnotherToStringCreator;\r\n"
+ + "\r\n"
+ + "public class A {\r\n"
+ + " \r\n"
+ + " boolean aBool;\r\n"
+ + " int anInt;\r\n"
+ + " String aString;\r\n"
+ + " A anA;\r\n"
+ + " float aFloatMethod() {\r\n"
+ + " return 3.3f;\r\n"
+ + " }\r\n"
+ + " String aStringMethod() {\r\n"
+ + " return \"\";\r\n"
+ + " }\r\n"
+ + " int[] anArrayMethod() {\r\n"
+ + " return new int[0];\r\n"
+ + " }\r\n"
+ + " @Override\r\n"
+ + " public String toString() {\r\n"
+ + " AnotherToStringCreator creator = new AnotherToStringCreator(this);\r\n"
+ + " creator.addSth(aStringMethod(), \"aStringMethod()\");\r\n"
+ + " creator.addSth(aFloatMethod(), \"aFloatMethod()\");\r\n"
+ + " creator.addSth(anArrayMethod(), \"anArrayMethod()\");\r\n"
+ + " creator.addSth(aBool, \"aBool\");\r\n"
+ + " creator.addSth(aString, \"aString\");\r\n"
+ + " creator.addSth(\"anInt\", anInt);\r\n"
+ + " return creator.getResult();\r\n"
+ + " }\r\n"
+ + "\r\n"
+ + "}";
compareSource(expected, a.getSource());
}
/**
- * Spring ToStringCreator - unique names needed
+ * Custom toString() builder - alternative class, unique names needed
*
* @throws Exception
*/
- public void testSpringCreatorUnique() throws Exception {
+ public void testAlternativeCustomBuilderUnique() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.List;\r\n"
+ "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " int[] intArray;\r\n" + " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " List list;\r\n"
@@ -2577,29 +2633,70 @@
IMember[] members= getMembers(a.getType("A"), new String[] { "aBool", "intArray", "stringArray", "AArray", "list", "hashMap", "wildCollection", "integerCollection", "builder", "buffer",
"maxLen", "len", "collection", "array", "creator" });
- fSettings2.toStringStyle= 6;
+ fSettings2.toStringStyle= 4;
+ fSettings2.customBuilderSettings.className= "org.another.pack.AnotherToStringCreator";
+ fSettings2.customBuilderSettings.label= "creator";
+ fSettings2.customBuilderSettings.appendMethod= "addSth";
+ fSettings2.customBuilderSettings.resultMethod= "getResult";
runOperation(a.getType("A"), members, null);
- String expected= "package p;\r\n" + "\r\n" + "import java.util.Collection;\r\n" + "import java.util.HashMap;\r\n" + "import java.util.List;\r\n" + "\r\n"
- + "import org.springframework.core.style.ToStringCreator;\r\n" + "\r\n" + "public class A {\r\n" + "\r\n" + " boolean aBool;\r\n" + " int[] intArray;\r\n"
- + " String[] stringArray;\r\n" + " A[] AArray;\r\n" + " List list;\r\n" + " HashMap hashMap;\r\n" + " Collection wildCollection;\r\n" + " Collection integerCollection;\r\n"
- + " Object builder;\r\n" + " Object buffer;\r\n" + " Object maxLen;\r\n" + " Object len;\r\n" + " Object collection;\r\n" + " Object array;\r\n" + " Object creator;\r\n"
- + " @Override\r\n" + " public String toString() {\r\n" + " ToStringCreator creator2 = new ToStringCreator(this);\r\n" + " creator2.append(\"aBool\", aBool);\r\n"
- + " creator2.append(\"intArray\", intArray);\r\n" + " creator2.append(\"stringArray\", stringArray);\r\n" + " creator2.append(\"AArray\", AArray);\r\n"
- + " creator2.append(\"list\", list);\r\n" + " creator2.append(\"hashMap\", hashMap);\r\n" + " creator2.append(\"wildCollection\", wildCollection);\r\n"
- + " creator2.append(\"integerCollection\", integerCollection);\r\n" + " creator2.append(\"builder\", builder);\r\n" + " creator2.append(\"buffer\", buffer);\r\n"
- + " creator2.append(\"maxLen\", maxLen);\r\n" + " creator2.append(\"len\", len);\r\n" + " creator2.append(\"collection\", collection);\r\n"
- + " creator2.append(\"array\", array);\r\n" + " creator2.append(\"creator\", creator);\r\n" + " return creator2.toString();\r\n" + " }\r\n" + "}\r\n" + "";
+ String expected= "package p;\r\n"
+ + "\r\n"
+ + "import java.util.Collection;\r\n"
+ + "import java.util.HashMap;\r\n"
+ + "import java.util.List;\r\n"
+ + "\r\n"
+ + "import org.another.pack.AnotherToStringCreator;\r\n"
+ + "\r\n"
+ + "public class A {\r\n"
+ + "\r\n"
+ + " boolean aBool;\r\n"
+ + " int[] intArray;\r\n"
+ + " String[] stringArray;\r\n"
+ + " A[] AArray;\r\n"
+ + " List list;\r\n"
+ + " HashMap hashMap;\r\n"
+ + " Collection wildCollection;\r\n"
+ + " Collection integerCollection;\r\n"
+ + " Object builder;\r\n"
+ + " Object buffer;\r\n"
+ + " Object maxLen;\r\n"
+ + " Object len;\r\n"
+ + " Object collection;\r\n"
+ + " Object array;\r\n"
+ + " Object creator;\r\n"
+ + " @Override\r\n"
+ + " public String toString() {\r\n"
+ + " AnotherToStringCreator creator2 = new AnotherToStringCreator(this);\r\n"
+ + " creator2.addSth(aBool, \"aBool\");\r\n"
+ + " creator2.addSth(intArray, \"intArray\");\r\n"
+ + " creator2.addSth(stringArray, \"stringArray\");\r\n"
+ + " creator2.addSth(AArray, \"AArray\");\r\n"
+ + " creator2.addSth(list, \"list\");\r\n"
+ + " creator2.addSth(hashMap, \"hashMap\");\r\n"
+ + " creator2.addSth(wildCollection, \"wildCollection\");\r\n"
+ + " creator2.addSth(integerCollection, \"integerCollection\");\r\n"
+ + " creator2.addSth(builder, \"builder\");\r\n"
+ + " creator2.addSth(buffer, \"buffer\");\r\n"
+ + " creator2.addSth(maxLen, \"maxLen\");\r\n"
+ + " creator2.addSth(len, \"len\");\r\n"
+ + " creator2.addSth(collection, \"collection\");\r\n"
+ + " creator2.addSth(array, \"array\");\r\n"
+ + " creator2.addSth(creator, \"creator\");\r\n"
+ + " return creator2.getResult();\r\n"
+ + " }\r\n"
+ + "}\r\n"
+ + "";
compareSource(expected, a.getSource());
}
/**
- * String ToStringCreator - skip nulls
+ * Custom toString() builder - alternative class, skip nulls
*
* @throws Exception
*/
- public void testSpringCreatorNulls() throws Exception {
+ public void testAlternativeCustomBuilderNulls() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
@@ -2607,38 +2704,16 @@
IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "aFloatMethod", "anArrayMethod", "aString", "aBool", "anInt" });
fSettings2.skipNulls= true;
- fSettings2.toStringStyle= 6;
- runOperation(a.getType("A"), members, null);
-
- String expected= "package p;\r\n" + "\r\n" + "import org.springframework.core.style.ToStringCreator;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
- + " int anInt;\r\n" + " String aString;\r\n" + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n"
- + " }\r\n" + " int[] anArrayMethod() {\r\n" + " return new int[0];\r\n" + " }\r\n" + " @Override\r\n" + " public String toString() {\r\n"
- + " ToStringCreator creator = new ToStringCreator(this);\r\n" + " if (aStringMethod() != null) {\r\n" + " creator.append(\"aStringMethod()\", aStringMethod());\r\n" + " }\r\n"
- + " creator.append(\"aFloatMethod()\", aFloatMethod());\r\n" + " if (anArrayMethod() != null) {\r\n" + " creator.append(\"anArrayMethod()\", anArrayMethod());\r\n" + " }\r\n"
- + " if (aString != null) {\r\n" + " creator.append(\"aString\", aString);\r\n" + " }\r\n" + " creator.append(\"aBool\", aBool);\r\n" + " creator.append(\"anInt\", anInt);\r\n"
- + " return creator.toString();\r\n" + " }\r\n" + "\r\n" + "}";
-
- compareSource(expected, a.getSource());
- }
-
- /**
- * Spring ToStringCreator, chained calls - basic case
- *
- * @throws Exception
- */
- public void testChainedSpringCreator() throws Exception {
-
- ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
- + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
- + " return new int[0];\r\n" + " }\r\n" + "\r\n" + "}", true, null);
-
- IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "aFloatMethod", "anArrayMethod", "aBool", "aString", "anInt" });
- fSettings2.toStringStyle= 7;
+ fSettings2.toStringStyle= 4;
+ fSettings2.customBuilderSettings.className= "org.another.pack.AnotherToStringCreator";
+ fSettings2.customBuilderSettings.label= "creator";
+ fSettings2.customBuilderSettings.appendMethod= "addSth";
+ fSettings2.customBuilderSettings.resultMethod= "getResult";
runOperation(a.getType("A"), members, null);
String expected= "package p;\r\n"
+ "\r\n"
- + "import org.springframework.core.style.ToStringCreator;\r\n"
+ + "import org.another.pack.AnotherToStringCreator;\r\n"
+ "\r\n"
+ "public class A {\r\n"
+ " \r\n"
@@ -2657,36 +2732,204 @@
+ " }\r\n"
+ " @Override\r\n"
+ " public String toString() {\r\n"
- + " ToStringCreator creator = new ToStringCreator(this);\r\n"
- + " creator.append(\"aStringMethod()\", aStringMethod()).append(\"aFloatMethod()\", aFloatMethod()).append(\"anArrayMethod()\", anArrayMethod()).append(\"aBool\", aBool).append(\"aString\", aString).append(\"anInt\", anInt);\r\n"
- + " return creator.toString();\r\n" + " }\r\n" + "\r\n" + "}";
+ + " AnotherToStringCreator creator = new AnotherToStringCreator(this);\r\n"
+ + " if (aStringMethod() != null) {\r\n"
+ + " creator.addSth(aStringMethod(), \"aStringMethod()\");\r\n"
+ + " }\r\n"
+ + " creator.addSth(aFloatMethod(), \"aFloatMethod()\");\r\n"
+ + " if (anArrayMethod() != null) {\r\n"
+ + " creator.addSth(anArrayMethod(), \"anArrayMethod()\");\r\n"
+ + " }\r\n"
+ + " if (aString != null) {\r\n"
+ + " creator.addSth(aString, \"aString\");\r\n"
+ + " }\r\n"
+ + " creator.addSth(aBool, \"aBool\");\r\n"
+ + " creator.addSth(\"anInt\", anInt);\r\n"
+ + " return creator.getResult();\r\n"
+ + " }\r\n"
+ + "\r\n"
+ + "}";
compareSource(expected, a.getSource());
}
/**
- * String ToStringCreator, chained calls - skip nulls
+ * Custom toString() builder - alternative class, chained calls
*
* @throws Exception
*/
- public void testChainedSpringCreatorNulls() throws Exception {
+ public void testChainedAlternativeCustomBuilderCreator() throws Exception {
ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
+ " return new int[0];\r\n" + " }\r\n" + "\r\n" + "}", true, null);
- IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "aFloatMethod", "anArrayMethod", "aString", "aBool", "anInt" });
+ IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "aFloatMethod", "anArrayMethod", "aBool", "aString", "anInt" });
+ fSettings2.toStringStyle= 4;
+ fSettings2.customBuilderSettings.className= "org.another.pack.AnotherToStringCreator";
+ fSettings2.customBuilderSettings.label= "creator";
+ fSettings2.customBuilderSettings.appendMethod= "addSth";
+ fSettings2.customBuilderSettings.resultMethod= "getResult";
+ fSettings2.customBuilderSettings.chainCalls= true;
+ runOperation(a.getType("A"), members, null);
+
+ String expected= "package p;\r\n" +
+ "\r\n" +
+ "import org.another.pack.AnotherToStringCreator;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " \r\n" +
+ " boolean aBool;\r\n" +
+ " int anInt;\r\n" +
+ " String aString;\r\n" +
+ " A anA;\r\n" +
+ " float aFloatMethod() {\r\n" +
+ " return 3.3f;\r\n" +
+ " }\r\n" +
+ " String aStringMethod() {\r\n" +
+ " return \"\";\r\n" +
+ " }\r\n" +
+ " int[] anArrayMethod() {\r\n" +
+ " return new int[0];\r\n" +
+ " }\r\n" +
+ " @Override\r\n" +
+ " public String toString() {\r\n" +
+ " AnotherToStringCreator creator = new AnotherToStringCreator(this);\r\n" +
+ " creator.addSth(aStringMethod(), \"aStringMethod()\").addSth(aFloatMethod(), \"aFloatMethod()\").addSth(anArrayMethod(), \"anArrayMethod()\").addSth(aBool, \"aBool\");\r\n" +
+ " creator.addSth(aString, \"aString\").addSth(\"anInt\", anInt);\r\n" +
+ " return creator.getResult();\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ "}";
+
+ compareSource(expected, a.getSource());
+ }
+
+ /**
+ * Custom toString() builder - alternative class, chained calls, skip nulls
+ *
+ * @throws Exception
+ */
+ public void testChainedAlternativeCustomBuilderNulls() throws Exception {
+
+ ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
+ + " return new int[0];\r\n" + " }\r\n" + "\r\n" + "}", true, null);
+
+ IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "anArrayMethod", "aString", "aFloatMethod", "aBool", "anInt" });
+ fSettings2.skipNulls= true;
+ fSettings2.toStringStyle= 4;
+ fSettings2.customBuilderSettings.className= "org.another.pack.AnotherToStringCreator";
+ fSettings2.customBuilderSettings.label= "creator";
+ fSettings2.customBuilderSettings.appendMethod= "addSth";
+ fSettings2.customBuilderSettings.resultMethod= "getResult";
+ fSettings2.customBuilderSettings.chainCalls= true;
+ runOperation(a.getType("A"), members, null);
+
+ String expected= "package p;\r\n" +
+ "\r\n" +
+ "import org.another.pack.AnotherToStringCreator;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " \r\n" +
+ " boolean aBool;\r\n" +
+ " int anInt;\r\n" +
+ " String aString;\r\n" +
+ " A anA;\r\n" +
+ " float aFloatMethod() {\r\n" +
+ " return 3.3f;\r\n" +
+ " }\r\n" +
+ " String aStringMethod() {\r\n" +
+ " return \"\";\r\n" +
+ " }\r\n" +
+ " int[] anArrayMethod() {\r\n" +
+ " return new int[0];\r\n" +
+ " }\r\n" +
+ " @Override\r\n" +
+ " public String toString() {\r\n" +
+ " AnotherToStringCreator creator = new AnotherToStringCreator(this);\r\n" +
+ " if (aStringMethod() != null) {\r\n" +
+ " creator.addSth(aStringMethod(), \"aStringMethod()\");\r\n" +
+ " }\r\n" +
+ " if (anArrayMethod() != null) {\r\n" +
+ " creator.addSth(anArrayMethod(), \"anArrayMethod()\");\r\n" +
+ " }\r\n" +
+ " if (aString != null) {\r\n" +
+ " creator.addSth(aString, \"aString\");\r\n" +
+ " }\r\n" +
+ " creator.addSth(aFloatMethod(), \"aFloatMethod()\").addSth(aBool, \"aBool\");\r\n" +
+ " creator.addSth(\"anInt\", anInt);\r\n" +
+ " return creator.getResult();\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ "}";
+
+ compareSource(expected, a.getSource());
+ }
+
+ /**
+ * Custom toString() builder - alternative class with append method that takes only one argument
+ * for most of the types
+ *
+ * @throws Exception
+ */
+ public void testChainedOneArgumentCustomBuilders() throws Exception {
+
+ ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n" + " int anInt;\r\n" + " String aString;\r\n"
+ + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n" + " }\r\n" + " int[] anArrayMethod() {\r\n"
+ + " return new int[0];\r\n" + " }\r\n" + "\r\n" + "}", true, null);
+
+ IPackageFragment packageFragment= fRoot.createPackageFragment("com.simple.pack", true, null);
+ ICompilationUnit compilationUnit= packageFragment.getCompilationUnit("ToStringBuilder.java");
+ compilationUnit
+ .createType(
+ "package com.simple.pack;\npublic class ToStringBuilder {\npublic ToStringBuilder(Object o){\n}\npublic ToStringBuilder append(Object o){\nreturn null;\n}\npublic ToStringBuilder append(String s1, String s2) {\nreturn null;\n}\npublic String toString(){\nreturn null;\n}\n}\n",
+ null, true, null);
+
+ IMember[] members= getMembers(a.getType("A"), new String[] { "aStringMethod", "anArrayMethod", "aString", "aFloatMethod", "aBool", "anInt" });
fSettings2.skipNulls= true;
- fSettings2.toStringStyle= 7;
+ fSettings2.customBuilderSettings.className= "com.simple.pack.ToStringBuilder";
+ fSettings2.toStringStyle= 4;
runOperation(a.getType("A"), members, null);
- String expected= "package p;\r\n" + "\r\n" + "import org.springframework.core.style.ToStringCreator;\r\n" + "\r\n" + "public class A {\r\n" + " \r\n" + " boolean aBool;\r\n"
- + " int anInt;\r\n" + " String aString;\r\n" + " A anA;\r\n" + " float aFloatMethod() {\r\n" + " return 3.3f;\r\n" + " }\r\n" + " String aStringMethod() {\r\n" + " return \"\";\r\n"
- + " }\r\n" + " int[] anArrayMethod() {\r\n" + " return new int[0];\r\n" + " }\r\n" + " @Override\r\n" + " public String toString() {\r\n"
- + " ToStringCreator creator = new ToStringCreator(this);\r\n" + " if (aStringMethod() != null) {\r\n" + " creator.append(\"aStringMethod()\", aStringMethod());\r\n" + " }\r\n"
- + " creator.append(\"aFloatMethod()\", aFloatMethod());\r\n" + " if (anArrayMethod() != null) {\r\n" + " creator.append(\"anArrayMethod()\", anArrayMethod());\r\n" + " }\r\n"
- + " if (aString != null) {\r\n" + " creator.append(\"aString\", aString);\r\n" + " }\r\n" + " creator.append(\"aBool\", aBool).append(\"anInt\", anInt);\r\n"
- + " return creator.toString();\r\n" + " }\r\n" + "\r\n" + "}";
+ String expected= "package p;\r\n" +
+ "\r\n" +
+ "import com.simple.pack.ToStringBuilder;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " \r\n" +
+ " boolean aBool;\r\n" +
+ " int anInt;\r\n" +
+ " String aString;\r\n" +
+ " A anA;\r\n" +
+ " float aFloatMethod() {\r\n" +
+ " return 3.3f;\r\n" +
+ " }\r\n" +
+ " String aStringMethod() {\r\n" +
+ " return \"\";\r\n" +
+ " }\r\n" +
+ " int[] anArrayMethod() {\r\n" +
+ " return new int[0];\r\n" +
+ " }\r\n" +
+ " @Override\r\n" +
+ " public String toString() {\r\n" +
+ " ToStringBuilder builder = new ToStringBuilder(this);\r\n" +
+ " if (aStringMethod() != null) {\r\n" +
+ " builder.append(\"aStringMethod()\", aStringMethod());\r\n" +
+ " }\r\n" +
+ " if (anArrayMethod() != null) {\r\n" +
+ " builder.append(anArrayMethod());\r\n" +
+ " }\r\n" +
+ " if (aString != null) {\r\n" +
+ " builder.append(\"aString\", aString);\r\n" +
+ " }\r\n" +
+ " builder.append(aFloatMethod());\r\n" +
+ " builder.append(aBool);\r\n" +
+ " builder.append(anInt);\r\n" +
+ " return builder.toString();\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ "}";
compareSource(expected, a.getSource());
}
#P org.eclipse.jdt.ui
Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/CodeGenerationMessages.properties
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/CodeGenerationMessages.properties,v
retrieving revision 1.30
diff -u -r1.30 CodeGenerationMessages.properties
--- core extension/org/eclipse/jdt/internal/corext/codemanipulation/CodeGenerationMessages.properties 30 Mar 2009 10:45:07 -0000 1.30
+++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/CodeGenerationMessages.properties 17 Apr 2009 14:18:18 -0000
@@ -8,6 +8,7 @@
# Contributors:
# IBM Corporation - initial API and implementation
# Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
+# Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
###############################################################################
AddGetterSetterOperation_description=Generate Getters and Setters...
AddGetterSetterOperation_error_input_type_not_found=Could not find the selected type element
@@ -35,8 +36,7 @@
GenerateHashCodeEqualsOperation_hash_code_argument=the array to create a hash code value for
GenerateHashCodeEqualsOperation_tag_return=@return
GenerateHashCodeEqualsOperation_return_comment=a hash code value for the array
-GenerateToStringOperation_apache_ToStringBilder_chained_style_name=Apache ToStringBuilder - chained calls
-GenerateToStringOperation_apache_ToStringBuilder_style_name=Apache ToStringBuilder
+GenerateToStringOperation_customStringBuilder_style_name=Custom toString() builder
GenerateToStringOperation_objectClassNameVariableDescription=Inserts the name of this class
GenerateToStringOperation_objectClassGetNameVariableDescription=Inserts a call to this.getClass().getName()
@@ -51,10 +51,8 @@
GenerateToStringOperation_description=Adding toString() method...
GenerateToStringOperation_error_dialog_title=Problem with toString() generation
GenerateToStringOperation_invalid_message=The extension ''{0}'' has become invalid.
-GenerateToStringOperation_spring_ToStringCreator_chained_style_name=Spring ToStringCreator - chained calls
-GenerateToStringOperation_spring_ToStringCreator_style_name=Spring ToStringCreator
GenerateToStringOperation_string_format_style_name=String.format/MessageFormat
GenerateToStringOperation_StringBuilder_chained_style_name=StringBuilder/StringBuffer - chained calls
GenerateToStringOperation_stringBuilder_style_name=StringBuilder/StringBuffer
GenerateToStringOperation_stringConcatenation_style_name=String concatenation
-GenerateToStringOperation_warning_no_arrays_collections_with_this_style=It is not recommended to enable "Ignore arrays' default toString" or "Limit number of items in arrays/collections/maps" options with selected code style as it might lead to undesired results.
+GenerateToStringOperation_warning_no_arrays_collections_with_this_style=It is not recommended to enable "List contents of arrays instead of using native toString" or "Limit number of items in arrays/collections/maps" options with selected code style as it might lead to undesired results.
Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/CodeGenerationMessages.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/CodeGenerationMessages.java,v
retrieving revision 1.18
diff -u -r1.18 CodeGenerationMessages.java
--- core extension/org/eclipse/jdt/internal/corext/codemanipulation/CodeGenerationMessages.java 30 Mar 2009 10:45:07 -0000 1.18
+++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/CodeGenerationMessages.java 17 Apr 2009 14:18:18 -0000
@@ -45,8 +45,7 @@
public static String GenerateHashCodeEqualsOperation_hash_code_argument;
public static String GenerateHashCodeEqualsOperation_tag_return;
public static String GenerateHashCodeEqualsOperation_return_comment;
- public static String GenerateToStringOperation_apache_ToStringBilder_chained_style_name;
- public static String GenerateToStringOperation_apache_ToStringBuilder_style_name;
+ public static String GenerateToStringOperation_customStringBuilder_style_name;
public static String GenerateToStringOperation_objectClassGetNameVariableDescription;
public static String GenerateToStringOperation_objectClassNameVariableDescription;
public static String GenerateToStringOperation_objectHashCodeVariableDescription;
@@ -59,8 +58,6 @@
public static String GenerateToStringOperation_memberNameVariableDescription;
public static String GenerateToStringOperation_memberValueVariableDescription;
public static String GenerateToStringOperation_otherFieldsVariableDescription;
- public static String GenerateToStringOperation_spring_ToStringCreator_chained_style_name;
- public static String GenerateToStringOperation_spring_ToStringCreator_style_name;
public static String GenerateToStringOperation_string_format_style_name;
public static String GenerateToStringOperation_StringBuilder_chained_style_name;
public static String GenerateToStringOperation_stringBuilder_style_name;
Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ToStringGenerationSettings.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ToStringGenerationSettings.java,v
retrieving revision 1.1
diff -u -r1.1 ToStringGenerationSettings.java
--- core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ToStringGenerationSettings.java 9 Mar 2009 19:20:35 -0000 1.1
+++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ToStringGenerationSettings.java 17 Apr 2009 14:18:19 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
+ * Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
*******************************************************************************/
package org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration;
@@ -31,7 +32,40 @@
public static final String SETTINGS_TEMPLATE_NAMES= "ToStringTemplateNames"; //$NON-NLS-1$
- public static final String SETTINGS_TEMPLATES= "ToStringTemplates"; //$NON-NLS-1$
+ public static final String SETTINGS_TEMPLATES= "ToStringTemplates"; //$NON-NLS-1$
+
+ public static final String SETTINGS_CUSTOMBUILDER_CLASS= "CustomBuilderClass"; //$NON-NLS-1$
+
+ public static final String SETTINGS_CUSTOMBUILDER_LABEL= "CustomBuilderLabel"; //$NON-NLS-1$
+
+ public static final String SETTINGS_CUSTOMBUILDER_APPENDMETHOD= "CustomBuilderAppendMethod"; //$NON-NLS-1$
+
+ public static final String SETTINGS_CUSTOMBUILDER_RESULTMETHOD= "CustomBuilderResultMethod"; //$NON-NLS-1$
+
+ public static final String SETTINGS_CUSTOMBUILDER_CHAINCALLS= "CustomBuilderChainCalls"; //$NON-NLS-1$
+
+ /**
+ * Container for settings specific for custom toString() generator code style
+ */
+ public static class CustomBuilderSettings {
+ /**
+ * what class should be used as a custom toString() builder (this is a fully qualified and
+ * Parameterized name)
+ **/
+ public String className;
+
+ /** identifier for a custom toString() builder in generated code **/
+ public String label;
+
+ /** name of a custom toString() builder's methods that should be called to append content **/
+ public String appendMethod;
+
+ /** name of a custom toString() builder method that should be called to retrieve result **/
+ public String resultMethod;
+
+ /** should custom toString() builder method calls be joined into chains? **/
+ public boolean chainCalls;
+ }
/** which template should be used to format the output of the toString() method? */
public int stringFormatTemplateNumber;
@@ -70,20 +104,32 @@
/** can generated code use jdk 1.6 API? **/
public boolean is60orHigher;
+ /** settings specific for custom builder code style **/
+ public CustomBuilderSettings customBuilderSettings;
+
+ private IDialogSettings dialogSettings;
+
public ToStringGenerationSettings(IDialogSettings dialogSettings) {
+ this.dialogSettings= dialogSettings;
limitElements= asBoolean(dialogSettings.get(SETTINGS_LIMITELEMENTS), false);
customArrayToString= asBoolean(dialogSettings.get(SETTINGS_IGNOREDEFAULT), true);
toStringStyle= asInt(dialogSettings.get(SETTINGS_STRINGSTYLE), 0);
limitValue= asInt(dialogSettings.get(SETTINGS_LIMITVALUE), 10);
skipNulls= asBoolean(dialogSettings.get(SETTINGS_SKIPNULLS), false);
stringFormatTemplateNumber= asInt(dialogSettings.get(SETTINGS_SELECTED_TEMPLATE), 0);
+ customBuilderSettings= new CustomBuilderSettings();
+ customBuilderSettings.className= asString(dialogSettings.get(SETTINGS_CUSTOMBUILDER_CLASS), ""); //$NON-NLS-1$
+ customBuilderSettings.label= asString(dialogSettings.get(SETTINGS_CUSTOMBUILDER_LABEL), "builder"); //$NON-NLS-1$
+ customBuilderSettings.appendMethod= asString(dialogSettings.get(SETTINGS_CUSTOMBUILDER_APPENDMETHOD), "append"); //$NON-NLS-1$
+ customBuilderSettings.resultMethod= asString(dialogSettings.get(SETTINGS_CUSTOMBUILDER_RESULTMETHOD), "toString"); //$NON-NLS-1$
+ customBuilderSettings.chainCalls= asBoolean(dialogSettings.get(SETTINGS_CUSTOMBUILDER_CHAINCALLS), false);
}
public ToStringGenerationSettings() {
}
- public void writeDialogSettings(IDialogSettings dialogSettings) {
+ public void writeDialogSettings() {
dialogSettings.put(SETTINGS_LIMITELEMENTS, limitElements);
dialogSettings.put(SETTINGS_IGNOREDEFAULT, customArrayToString);
dialogSettings.put(SETTINGS_STRINGSTYLE, toStringStyle);
@@ -91,18 +137,56 @@
dialogSettings.put(SETTINGS_SKIPNULLS, skipNulls);
dialogSettings.put(SETTINGS_SELECTED_TEMPLATE, stringFormatTemplateNumber);
}
-
+
+ /**
+ * Returns a copy of customBuilderSettings. Changes made in the returned object will not affect
+ * this settings object. To save changes made in returned object, use
+ * {@link #writeCustomBuilderSettings(ToStringGenerationSettings.CustomBuilderSettings)}.
+ *
+ * @return copy of custom builder settings object
+ */
+ public CustomBuilderSettings getCustomBuilderSettings() {
+ CustomBuilderSettings result= new CustomBuilderSettings();
+ result.className= customBuilderSettings.className;
+ result.label= customBuilderSettings.label;
+ result.appendMethod= customBuilderSettings.appendMethod;
+ result.resultMethod= customBuilderSettings.resultMethod;
+ result.chainCalls= customBuilderSettings.chainCalls;
+ return result;
+ }
+
+ /**
+ * Writes given custom builder settings object to the underlying dialog settings.
+ *
+ * @param customBuilderSettings1 settings to save
+ */
+ public void writeCustomBuilderSettings(CustomBuilderSettings customBuilderSettings1) {
+ dialogSettings.put(SETTINGS_CUSTOMBUILDER_CLASS, customBuilderSettings1.className);
+ dialogSettings.put(SETTINGS_CUSTOMBUILDER_LABEL, customBuilderSettings1.label);
+ dialogSettings.put(SETTINGS_CUSTOMBUILDER_APPENDMETHOD, customBuilderSettings1.appendMethod);
+ dialogSettings.put(SETTINGS_CUSTOMBUILDER_RESULTMETHOD, customBuilderSettings1.resultMethod);
+ dialogSettings.put(SETTINGS_CUSTOMBUILDER_CHAINCALLS, customBuilderSettings1.chainCalls);
+ customBuilderSettings= customBuilderSettings1;
+ }
+
private boolean asBoolean(String string, boolean defaultValue) {
if (string != null) {
return StringConverter.asBoolean(string, defaultValue);
}
return defaultValue;
}
-
+
private static int asInt(String string, int defaultValue) {
if (string != null) {
return StringConverter.asInt(string, defaultValue);
}
return defaultValue;
}
-}
\ No newline at end of file
+
+ private static String asString(String string, String defaultValue) {
+ if (string != null) {
+ return string;
+ }
+ return defaultValue;
+ }
+}
Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/GenerateToStringOperation.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/GenerateToStringOperation.java,v
retrieving revision 1.1
diff -u -r1.1 GenerateToStringOperation.java
--- core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/GenerateToStringOperation.java 9 Mar 2009 19:20:35 -0000 1.1
+++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/GenerateToStringOperation.java 17 Apr 2009 14:18:19 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Mateusz Matela and others.
+ * Copyright (c) 2009 Mateusz Matela and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
+ * Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
*******************************************************************************/
package org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration;
@@ -171,28 +172,15 @@
public static final int STRING_FORMAT= 3;
- public static final int APACHE_BUILDER= 4;
-
- public static final int APACHE_BUILDER_CHAINED= 5;
-
- public static final int SPRING_CREATOR= 6;
-
- public static final int SPRING_CREATOR_CHAINED= 7;
-
-// public static final int ID_START= 8;
+ public static final int CUSTOM_BUILDER= 4;
private final static String[] hardcoded_styles= {
CodeGenerationMessages.GenerateToStringOperation_stringConcatenation_style_name,
CodeGenerationMessages.GenerateToStringOperation_stringBuilder_style_name,
CodeGenerationMessages.GenerateToStringOperation_StringBuilder_chained_style_name,
CodeGenerationMessages.GenerateToStringOperation_string_format_style_name,
-// CodeGenerationMessages.GenerateToStringOperation_apache_ToStringBuilder_style_name,
-// CodeGenerationMessages.GenerateToStringOperation_apache_ToStringBilder_chained_style_name,
-// CodeGenerationMessages.GenerateToStringOperation_spring_ToStringCreator_style_name,
-// CodeGenerationMessages.GenerateToStringOperation_spring_ToStringCreator_chained_style_name
- };
-
-
+ CodeGenerationMessages.GenerateToStringOperation_customStringBuilder_style_name
+ };
/**
* @return Array containing names of implemented code styles
@@ -217,17 +205,10 @@
return new StringBuilderChainGenerator();
case STRING_FORMAT:
return new StringFormatGenerator();
- case APACHE_BUILDER:
- return new ApacheBuilderSpringCreatorGenerator("org.apache.commons.lang.builder.ToStringBuilder", "builder", false); //$NON-NLS-1$ //$NON-NLS-2$
- case APACHE_BUILDER_CHAINED:
- return new ApacheBuilderSpringCreatorGenerator("org.apache.commons.lang.builder.ToStringBuilder", "builder", true); //$NON-NLS-1$ //$NON-NLS-2$
- case SPRING_CREATOR:
- return new ApacheBuilderSpringCreatorGenerator("org.springframework.core.style.ToStringCreator", "creator", false); //$NON-NLS-1$ //$NON-NLS-2$
- case SPRING_CREATOR_CHAINED:
- return new ApacheBuilderSpringCreatorGenerator("org.springframework.core.style.ToStringCreator", "creator", true); //$NON-NLS-1$ //$NON-NLS-2$
+ case CUSTOM_BUILDER:
+ return new CustomBuilderGenerator();
default:
- //unknown style
- return null;
+ throw new RuntimeException("Undefined toString() code style: " + toStringStyle); //$NON-NLS-1$
}
}
@@ -244,10 +225,10 @@
* Creates new GenerateToStringOperation
, using settings.toStringStyle
* field to choose the right subclass.
*
- * @param typeBinding binding for the type for which the toString() method will be created
+ * @param typeBinding binding for the type for which the toString() method will be created
* @param selectedBindings bindings for the typetype's members to be used in created method
* @param unit a compilation unit containing the type
- * @param elementPosition at this position in the compilation unit created method will be added
+ * @param elementPosition at this position in the compilation unit created method will be added
* @param settings the settings for toString() generator
* @return a ready to use GenerateToStringOperation
object
*/
Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ToStringGenerationContext.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ToStringGenerationContext.java,v
retrieving revision 1.1
diff -u -r1.1 ToStringGenerationContext.java
--- core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ToStringGenerationContext.java 9 Mar 2009 19:20:35 -0000 1.1
+++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ToStringGenerationContext.java 17 Apr 2009 14:18:19 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
+ * Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
*******************************************************************************/
package org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration;
@@ -28,6 +29,8 @@
private ITypeBinding fType;
private ToStringGenerationSettings fSettings;
+
+ private ToStringGenerationSettings.CustomBuilderSettings fCustomBuilderSettings;
private CompilationUnitRewrite fRewrite;
@@ -36,6 +39,7 @@
fParser= parser;
fSelectedMembers= selectedMembers;
fSettings= settings;
+ fCustomBuilderSettings= settings.getCustomBuilderSettings();
fType= type;
fRewrite= rewrite;
}
@@ -107,5 +111,25 @@
public boolean isSkipNulls() {
return fSettings.skipNulls;
}
+
+ public String getCustomBuilderClass() {
+ return fCustomBuilderSettings.className;
+ }
+
+ public String getCustomBuilderLabel() {
+ return fCustomBuilderSettings.label;
+ }
+
+ public String getCustomBuilderAppendMethod() {
+ return fCustomBuilderSettings.appendMethod;
+ }
+
+ public String getCustomBuilderResultMethod() {
+ return fCustomBuilderSettings.resultMethod;
+ }
+
+ public boolean isCustomBuilderChainedCalls() {
+ return fCustomBuilderSettings.chainCalls;
+ }
}
\ No newline at end of file
Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ApacheBuilderSpringCreatorGenerator.java
===================================================================
RCS file: core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ApacheBuilderSpringCreatorGenerator.java
diff -N core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ApacheBuilderSpringCreatorGenerator.java
--- core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/ApacheBuilderSpringCreatorGenerator.java 9 Mar 2009 19:20:35 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,150 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Mateusz Matela and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
- *******************************************************************************/
-package org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration;
-
-import org.eclipse.core.runtime.CoreException;
-
-import org.eclipse.ltk.core.refactoring.RefactoringStatus;
-
-import org.eclipse.jdt.core.NamingConventions;
-import org.eclipse.jdt.core.dom.ClassInstanceCreation;
-import org.eclipse.jdt.core.dom.Expression;
-import org.eclipse.jdt.core.dom.IfStatement;
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jdt.core.dom.MethodInvocation;
-import org.eclipse.jdt.core.dom.ReturnStatement;
-import org.eclipse.jdt.core.dom.StringLiteral;
-import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
-import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
-import org.eclipse.jdt.core.dom.InfixExpression.Operator;
-
-import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationMessages;
-
-
-/**
- *
- * Implementation of AbstractToStringGenerator
that creates toString()
- * method using external library. The library must deliver a stringBuilder with
- * append(name, value)
method, for example Apache ToStringBuilder or Spring Framework
- * ToStringCreator.
- *
- *
- * Generated methods look like this:
- *
- *
- * public String toString() {
- * StringBuilder builder= new StringBuilder();
- * builder.append("FooClass( field1=");
- * builder.append(field1);
- * builder.append(", field2=");
- * builder.append(field2);
- * builder.append(" )");
- * return builder.toString();
- * }
- *
- *
- *
- *
- * @since 3.5
- */
-public class ApacheBuilderSpringCreatorGenerator extends AbstractToStringGenerator {
- private String builderVariableName;
-
- private String importText;
-
- private boolean chained;
-
- public ApacheBuilderSpringCreatorGenerator(String importText, String builderName, boolean chained) {
- builderVariableName= builderName;
- this.importText= importText;
- this.chained= chained;
- }
-
- protected void initialize() {
- super.initialize();
- this.builderVariableName= createNameSuggestion(builderVariableName, NamingConventions.VK_PARAMETER);
- }
-
- public RefactoringStatus checkConditions() {
- RefactoringStatus status= super.checkConditions();
- if (fContext.isCustomArray() || fContext.isLimitItems())
- status.addWarning(CodeGenerationMessages.GenerateToStringOperation_warning_no_arrays_collections_with_this_style);
- return status;
- }
-
-
- protected void addElement(Object element) {
- }
-
- public MethodDeclaration generateToStringMethod() throws CoreException {
- initialize();
-
- //ToStringBuilder builder= new ToStringBuilder(this);
- VariableDeclarationFragment fragment= fAst.newVariableDeclarationFragment();
- fragment.setName(fAst.newSimpleName(builderVariableName));
- ClassInstanceCreation classInstance= fAst.newClassInstanceCreation();
- String typeName= addImport(importText);
- classInstance.setType(fAst.newSimpleType(fAst.newSimpleName(typeName)));
- classInstance.arguments().add(fAst.newThisExpression());
- fragment.setInitializer(classInstance);
- VariableDeclarationStatement vStatement= fAst.newVariableDeclarationStatement(fragment);
- vStatement.setType(fAst.newSimpleType(fAst.newName(typeName)));
- toStringMethod.getBody().statements().add(vStatement);
-
- Expression expression= null;
-
- for (int i= 0; i < getContext().getSelectedMembers().length; i++) {
- //builder.append("member", member);
- StringLiteral literal= fAst.newStringLiteral();
- literal.setLiteralValue(getMemberName(getContext().getSelectedMembers()[i], ToStringTemplateParser.MEMBER_NAME_PARENTHESIS_VARIABLE));
- MethodInvocation appendInvocation= fAst.newMethodInvocation();
- appendInvocation.setName(fAst.newSimpleName("append")); //$NON-NLS-1$
- appendInvocation.arguments().add(literal);
- appendInvocation.arguments().add(createMemberAccessExpression(getContext().getSelectedMembers()[i], false, getContext().isSkipNulls()));
-
- if (getContext().isSkipNulls() && !getMemberType(getContext().getSelectedMembers()[i]).isPrimitive()) {
- if (expression != null) {
- toStringMethod.getBody().statements().add(fAst.newExpressionStatement(expression));
- expression= null;
- }
- appendInvocation.setExpression(fAst.newSimpleName(builderVariableName));
- IfStatement ifStatement= fAst.newIfStatement();
- ifStatement.setExpression(createInfixExpression(createMemberAccessExpression(getContext().getSelectedMembers()[i], true, true), Operator.NOT_EQUALS, fAst.newNullLiteral()));
- ifStatement.setThenStatement(createOneStatementBlock(appendInvocation));
- toStringMethod.getBody().statements().add(ifStatement);
- } else {
- if (expression != null) {
- appendInvocation.setExpression(expression);
- } else {
- appendInvocation.setExpression(fAst.newSimpleName(builderVariableName));
- }
- if (chained) {
- expression= appendInvocation;
- } else {
- toStringMethod.getBody().statements().add(fAst.newExpressionStatement(appendInvocation));
- }
- }
- }
-
- if (expression != null) {
- toStringMethod.getBody().statements().add(fAst.newExpressionStatement(expression));
- }
- // return builder.toString();
- ReturnStatement rStatement= fAst.newReturnStatement();
- rStatement.setExpression(createMethodInvocation(builderVariableName, "toString", null)); //$NON-NLS-1$
- toStringMethod.getBody().statements().add(rStatement);
-
- complete();
-
- return toStringMethod;
- }
-
-}
Index: ui/org/eclipse/jdt/internal/ui/dialogs/GenerateToStringDialog.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/dialogs/GenerateToStringDialog.java,v
retrieving revision 1.4
diff -u -r1.4 GenerateToStringDialog.java
--- ui/org/eclipse/jdt/internal/ui/dialogs/GenerateToStringDialog.java 30 Mar 2009 13:03:56 -0000 1.4
+++ ui/org/eclipse/jdt/internal/ui/dialogs/GenerateToStringDialog.java 17 Apr 2009 14:18:24 -0000
@@ -8,9 +8,11 @@
* Contributors:
* Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
* Mateusz Matela - [toString] Template edit dialog has usability issues - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267916
+ * Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
*******************************************************************************/
package org.eclipse.jdt.internal.ui.dialogs;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -37,6 +39,7 @@
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.IDialogConstants;
@@ -58,19 +61,31 @@
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+import org.eclipse.ui.dialogs.SelectionDialog;
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.GenerateToStringOperation;
import org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringGenerationSettings;
import org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringTemplateParser;
+import org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringGenerationSettings.CustomBuilderSettings;
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
+import org.eclipse.jdt.ui.IJavaElementSearchConstants;
import org.eclipse.jdt.ui.JavaElementImageDescriptor;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jdt.ui.dialogs.TypeSelectionExtension;
import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.JavaPlugin;
@@ -80,6 +95,7 @@
import org.eclipse.jdt.internal.ui.util.SWTUtil;
import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
/**
* Dialog for the generate toString() action.
@@ -271,12 +287,14 @@
}
}
- private static class GenerateToStringValidator implements ISelectionStatusValidator {
+ private class GenerateToStringValidator implements ISelectionStatusValidator {
private int fNumFields;
private int fNumMethods;
+ private CustomBuilderValidator fValidator;
+
public GenerateToStringValidator(int fields, int methods) {
fNumFields= fields;
fNumMethods= methods;
@@ -284,6 +302,14 @@
public IStatus validate(Object[] selection) {
+ if (getGenerationSettings().toStringStyle == GenerateToStringOperation.CUSTOM_BUILDER) {
+ if (fValidator == null)
+ fValidator= new CustomBuilderValidator(getType().getJavaProject());
+ IStatus status= fValidator.revalidateAll(getGenerationSettings().getCustomBuilderSettings());
+ if (!status.isOK())
+ return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_selectioninfo_customBuilderConfigError);
+ }
+
int countFields= 0, countMethods= 0;
for (int index= 0; index < selection.length; index++) {
if (selection[index] instanceof IVariableBinding)
@@ -304,12 +330,12 @@
* Template number, -1 for new template.
*/
private final int templateNumber;
-
+
/**
* Initial template name, can be null
.
*/
private final String fInitialTemplateName;
-
+
private Text templateName;
private Text template;
@@ -327,7 +353,7 @@
fInitialTemplateName= templateNumber < 0 ? null : (String)templateNames.get(templateNumber);
setHelpAvailable(false);
}
-
+
protected boolean isResizable() {
return true;
}
@@ -377,7 +403,7 @@
//Ctrl+Enter should execute the default button, workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=145959
template.addTraverseListener(new TraverseListener() {
public void keyTraversed(TraverseEvent e) {
- if (e.detail == SWT.TRAVERSE_RETURN && (e.stateMask & SWT.MODIFIER_MASK) != 0) {
+ if (e.detail == SWT.TRAVERSE_RETURN && (e.stateMask & SWT.MODIFIER_MASK) != 0) {
buttonPressed(((Integer)getShell().getDefaultButton().getData()).intValue());
}
}
@@ -400,7 +426,7 @@
private String createNewTemplateName() {
if (!templateNames.contains(JavaUIMessages.GenerateToStringDialog_newTemplateName))
return JavaUIMessages.GenerateToStringDialog_newTemplateName;
-
+
int copyCount= 2;
String newName;
do {
@@ -447,25 +473,21 @@
private class Proposal implements IContentProposal {
final private String proposal;
- private String content;
+ private int position;
public Proposal(String proposal) {
this.proposal= proposal;
+ this.position= proposal.length();
}
public String getContent() {
- for (int i= 1; i < Math.min(proposal.length(), latestPosition); i++) {
- if (proposal.substring(0, i).equals(latestContents.substring(latestPosition - i, latestPosition))) {
- return content= proposal.substring(i);
- }
- }
- return proposal;
+ int overlap= stringOverlap(latestContents.substring(0, latestPosition), proposal);
+ position= proposal.length() - overlap;
+ return proposal.substring(overlap);
}
public int getCursorPosition() {
- if (content != null)
- return content.length();
- return proposal.length();
+ return position;
}
public String getDescription() {
@@ -477,24 +499,51 @@
}
}
- private IContentProposal[] proposals;
-
private String latestContents;
private int latestPosition;
public IContentProposal[] getProposals(String contents, int position) {
- if (proposals == null) {
- List proposalsList= new ArrayList();
- String[] tokens= parser.getVariables();
- for (int i= 0; i < tokens.length; i++) {
- proposalsList.add(new Proposal(tokens[i]));
- }
- proposals= (IContentProposal[])proposalsList.toArray(new IContentProposal[0]);
+ List primaryProposals= new ArrayList();
+ List secondaryProposals= new ArrayList();
+ String[] proposalStrings= parser.getVariables();
+ String contentToCursor= contents.substring(0, position);
+ for (int i= 0; i < proposalStrings.length; i++) {
+ if (stringOverlap(contentToCursor, proposalStrings[i]) > 0)
+ primaryProposals.add(new Proposal(proposalStrings[i]));
+ else
+ secondaryProposals.add(new Proposal(proposalStrings[i]));
}
+
this.latestContents= contents;
this.latestPosition= position;
- return proposals;
+
+ primaryProposals.addAll(secondaryProposals);
+ return (IContentProposal[])primaryProposals.toArray(new IContentProposal[0]);
+ }
+
+ /**
+ * Checks if the end of the first string is equal to the beginning of of the second
+ * string.
+ *
+ * @param s1 first String
+ * @param s2 second String
+ * @return length of overlapping segment (0 if strings don't overlap)
+ */
+ private int stringOverlap(String s1, String s2) {
+ int l1= s1.length();
+ for (int l= 1; l <= Math.min(s1.length(), s2.length()); l++) {
+ boolean ok= true;
+ for (int i= 0; i < l; i++) {
+ if (s1.charAt(l1 - l + i) != s2.charAt(i)) {
+ ok= false;
+ break;
+ }
+ }
+ if (ok)
+ return l;
+ }
+ return 0;
}
}
@@ -568,7 +617,7 @@
templateNames= new ArrayList(Arrays.asList(getTemplateNames()));
templates= new ArrayList(Arrays.asList(getTemplates(getDialogSettings())));
- selectedTemplateNumber= fGenerationSettings.stringFormatTemplateNumber;
+ selectedTemplateNumber= getGenerationSettings().stringFormatTemplateNumber;
refreshControls();
templateNameControl.addSelectionListener(new SelectionListener() {
@@ -599,7 +648,7 @@
private void applyChanges() {
getDialogSettings().put(ToStringGenerationSettings.SETTINGS_TEMPLATE_NAMES, (String[])templateNames.toArray(new String[0]));
getDialogSettings().put(ToStringGenerationSettings.SETTINGS_TEMPLATES, (String[])templates.toArray(new String[0]));
- fGenerationSettings.stringFormatTemplateNumber= Math.max(selectedTemplateNumber, 0);
+ getGenerationSettings().stringFormatTemplateNumber= Math.max(selectedTemplateNumber, 0);
somethingChanged= false;
getButton(APPLY_BUTTON).setEnabled(false);
}
@@ -680,6 +729,414 @@
}
}
+ private static class CustomBuilderValidator implements ISelectionStatusValidator {
+
+ private final static List fJavaKeyWords= Arrays.asList(new String[] { "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$
+ "if", "private", "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$ //$NON-NLS-17$ //$NON-NLS-18$
+ "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$ //$NON-NLS-17$ //$NON-NLS-18$ //$NON-NLS-19$
+ "while" }); //$NON-NLS-1$
+
+ private final IJavaProject fJavaProject;
+
+ private IType fLastValidBuilderType;
+
+ private List fLastValidAppendMethodSuggestions;
+
+ private List fLastValidResultMethodSuggestions;
+
+ public CustomBuilderValidator(IJavaProject javaProject) {
+ fJavaProject= javaProject;
+ }
+
+ public IStatus validateBuilderType(IType type) {
+ if (fLastValidBuilderType != null && fLastValidBuilderType.equals(type)) {
+ return new StatusInfo();
+ }
+
+ try {
+ IMethod[] methods= type.getMethods();
+ boolean foundConstructor= false;
+ for (int i= 0; i < methods.length; i++) {
+ if (methods[i].isConstructor() && Flags.isPublic(methods[i].getFlags())) {
+ String[] parameterTypes= methods[i].getParameterTypes();
+ if (parameterTypes.length == 1 && "java.lang.Object".equals(JavaModelUtil.getResolvedTypeName(parameterTypes[0], type))) { //$NON-NLS-1$
+ foundConstructor= true;
+ break;
+ }
+ }
+ }
+ if (!foundConstructor)
+ return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_noConstructorError);
+
+ List appendMethodSuggestions= getAppendMethodSuggestions(type);
+ if (appendMethodSuggestions.isEmpty())
+ return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_noAppendMethodError);
+
+ List resultMethodSuggestions= getResultMethodSuggestions(type);
+ if (resultMethodSuggestions.isEmpty())
+ return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_noResultMethodError);
+
+ fLastValidBuilderType= type;
+ fLastValidAppendMethodSuggestions= appendMethodSuggestions;
+ fLastValidResultMethodSuggestions= resultMethodSuggestions;
+ return new StatusInfo();
+ } catch (JavaModelException e1) {
+ return new StatusInfo(IStatus.WARNING, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_typeValidationError);
+ }
+ }
+
+ public IStatus validate(Object[] selection) {
+ return validateBuilderType(((IType)selection[0]));
+ }
+
+ public IStatus revalidateAll(CustomBuilderSettings builderSettings) {
+ try {
+ if (builderSettings.className.length() == 0) {
+ return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_noBuilderClassError);
+ }
+
+ IType type= findType(builderSettings.className);
+
+ if (type == null || !type.exists()) {
+ return new StatusInfo(IStatus.ERROR, MessageFormat.format(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_invalidClassError,
+ new String[] { builderSettings.className }));
+ }
+
+ IStatus typeValidation= validateBuilderType(type);
+ if (!typeValidation.isOK())
+ return typeValidation;
+
+ if (!getAppendMethodSuggestions(type).contains(builderSettings.appendMethod))
+ return new StatusInfo(IStatus.ERROR, MessageFormat.format(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_invalidAppendMethodError,
+ new String[] { builderSettings.appendMethod }));
+
+ if (!getResultMethodSuggestions(type).contains(builderSettings.resultMethod))
+ return new StatusInfo(IStatus.ERROR, MessageFormat.format(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_invalidResultMethodError,
+ new String[] { builderSettings.resultMethod }));
+
+ if (!isValidJavaIdentifier(builderSettings.label))
+ return new StatusInfo(IStatus.ERROR, MessageFormat.format(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_invalidLabelError, new String[] { builderSettings.label }));
+
+ } catch (JavaModelException e) {
+ return new StatusInfo(IStatus.WARNING, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_dataBalidationError);
+ }
+ return new StatusInfo();
+ }
+
+ public IType findType(String builderClassName) throws JavaModelException {
+ if (fLastValidBuilderType != null && builderClassName.equals(fLastValidBuilderType.getFullyQualifiedParameterizedName())) {
+ return fLastValidBuilderType;
+ }
+
+ return fJavaProject.findType(builderClassName, (IProgressMonitor)null);
+ }
+
+ public List getAppendMethodSuggestions(final IType type) throws JavaModelException {
+ if (fLastValidBuilderType != null && fLastValidBuilderType.equals(type)) {
+ return fLastValidAppendMethodSuggestions;
+ }
+ return getMethodSuggestions(type, new MethodChecker() {
+ public boolean isMethodOK(IMethod method) throws JavaModelException {
+ if (!Flags.isPublic(method.getFlags()) || method.isConstructor())
+ return false;
+ /* To be an append method, it must take exactly one
+ * Object parameter, and optionally one String parameter. */
+ String[] parameterTypes= method.getParameterTypes();
+ if (parameterTypes.length == 0 || parameterTypes.length > 2) {
+ return false;
+ }
+ int countObjects= 0, countStrings= 0;
+ for (int i= 0; i < parameterTypes.length; i++) {
+ String resolvedParameterTypeName= JavaModelUtil.getResolvedTypeName(parameterTypes[i], type);
+ if ("java.lang.Object".equals(resolvedParameterTypeName))//$NON-NLS-1$
+ countObjects++;
+ if ("java.lang.String".equals(resolvedParameterTypeName))//$NON-NLS-1$
+ countStrings++;
+ }
+ return countObjects == 1 && countObjects + countStrings == parameterTypes.length;
+
+ }
+ });
+ }
+
+ public List getResultMethodSuggestions(final IType type) throws JavaModelException {
+ if (fLastValidBuilderType != null && fLastValidBuilderType.equals(type)) {
+ return fLastValidResultMethodSuggestions;
+ }
+ return getMethodSuggestions(type, new MethodChecker() {
+ public boolean isMethodOK(IMethod method) throws JavaModelException {
+ return Flags.isPublic(method.getFlags()) && method.getParameterTypes().length == 0 && "java.lang.String".equals(JavaModelUtil.getResolvedTypeName(method.getReturnType(), type)); //$NON-NLS-1$
+ }
+ });
+ }
+
+ private interface MethodChecker {
+ boolean isMethodOK(IMethod method) throws JavaModelException;
+ }
+
+ private List getMethodSuggestions(IType type, MethodChecker checker) throws JavaModelException {
+ ArrayList result= new ArrayList();
+ IType[] classes= type.newSupertypeHierarchy(null).getAllClasses();
+ for (int i= 0; i < classes.length; i++) {
+ IMethod[] methods= classes[i].getMethods();
+ for (int j= 0; j < methods.length; j++) {
+ if (checker.isMethodOK(methods[j])) {
+ String name= methods[j].getElementName();
+ if (!result.contains(name))
+ result.add(name);
+ }
+ }
+ }
+ return result;
+ }
+
+ private boolean isValidJavaIdentifier(String identifier) {
+
+ if (identifier.length() == 0 || !Character.isJavaIdentifierStart(identifier.charAt(0))) {
+ return false;
+ }
+ for (int i= 1; i < identifier.length(); i++) {
+ if (!Character.isJavaIdentifierPart(identifier.charAt(i))) {
+ return false;
+ }
+ }
+ return !fJavaKeyWords.contains(identifier);
+ }
+ }
+
+ private class CustomBuilderConfigurationDialog extends StatusDialog {
+
+ private final int APPLY_BUTTON= IDialogConstants.CLIENT_ID + 1;
+
+ /**
+ * Extension for class selection dialog - validates selected type
+ */
+ private final TypeSelectionExtension fExtension= new TypeSelectionExtension() {
+ public ISelectionStatusValidator getSelectionValidator() {
+ return getValidator();
+ }
+ };
+
+ /**
+ * Listener for text fields - updates combos and validates entered data
+ */
+ private final ModifyListener modifyListener= new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ if (e.widget == fBuilderClassName) {
+ fBuilderSettings.className= fBuilderClassName.getText();
+ updateCombos();
+ } else if (e.widget == fBuilderLabel)
+ fBuilderSettings.label= fBuilderLabel.getText();
+
+ IStatus status= getValidator().revalidateAll(fBuilderSettings);
+ updateStatus(status);
+
+ enableApplyButton();
+ }
+ };
+
+ private final CustomBuilderValidator fValidator= new CustomBuilderValidator(getType().getJavaProject());
+
+ private Text fBuilderClassName;
+
+ private Text fBuilderLabel;
+
+ private Combo fAppendMethodName;
+
+ private Combo fResultMethodName;
+
+ private Button fChainInvocations;
+
+ private ToStringGenerationSettings.CustomBuilderSettings fBuilderSettings;
+
+ private boolean somethingChanged= false;
+
+ public CustomBuilderConfigurationDialog(Shell parent) {
+ super(parent);
+ this.setShellStyle(this.getShellStyle() | SWT.RESIZE);
+ this.setHelpAvailable(false);
+ fBuilderSettings= getGenerationSettings().getCustomBuilderSettings();
+
+ }
+
+ public CustomBuilderValidator getValidator() {
+ return fValidator;
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ getShell().setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_windowTitle);
+
+ Composite composite= (Composite)super.createDialogArea(parent);
+ ((GridLayout)composite.getLayout()).numColumns= 3;
+ LayoutUtil.setWidthHint(composite, convertWidthInCharsToPixels(100));
+
+ Label label= new Label(composite, SWT.LEFT);
+ label.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_builderClassField);
+ fBuilderClassName= createTextField(composite, 1, fBuilderSettings.className);
+
+ Button button= new Button(composite, SWT.NONE);
+ button.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_browseButton);
+ setButtonLayoutData(button);
+ button.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ browseForBuilderClass();
+ }
+ });
+
+ label= new Label(composite, SWT.LEFT);
+ label.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_labelField);
+ fBuilderLabel= createTextField(composite, 2, fBuilderSettings.label);
+
+ label= new Label(composite, SWT.LEFT);
+ label.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_appendMethodField);
+ fAppendMethodName= new Combo(composite, SWT.READ_ONLY);
+ fAppendMethodName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+
+ label= new Label(composite, SWT.LEFT);
+ label.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_resultMethodField);
+ fResultMethodName= new Combo(composite, SWT.READ_ONLY);
+ fResultMethodName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+
+ updateCombos();
+ ModifyListener comboListener= new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ Combo c= (Combo)e.widget;
+ if (c.getText().length() > 0) {
+ if (c == fAppendMethodName)
+ fBuilderSettings.appendMethod= c.getText();
+ if (c == fResultMethodName)
+ fBuilderSettings.resultMethod= c.getText();
+ }
+ updateStatus(fValidator.revalidateAll(fBuilderSettings));
+ enableApplyButton();
+ }
+ };
+ fAppendMethodName.addModifyListener(comboListener);
+ fResultMethodName.addModifyListener(comboListener);
+ if (!select(fAppendMethodName, fBuilderSettings.appendMethod)) {
+ fAppendMethodName.select(0);
+ }
+ if (!select(fResultMethodName, fBuilderSettings.resultMethod)) {
+ fResultMethodName.select(0);
+ }
+
+ fChainInvocations= new Button(composite, SWT.CHECK);
+ fChainInvocations.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_chainedCallsCheckbox);
+ fChainInvocations.setSelection(fBuilderSettings.chainCalls);
+ fChainInvocations.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
+ fChainInvocations.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ fBuilderSettings.chainCalls= fChainInvocations.getSelection();
+ enableApplyButton();
+ }
+ });
+
+ return composite;
+ }
+
+ public void create() {
+ super.create();
+ IStatus status= getValidator().revalidateAll(fBuilderSettings);
+ updateStatus(status);
+ }
+
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ createButton(parent, APPLY_BUTTON, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_applyButton, false).setEnabled(false);
+ }
+
+ private void enableApplyButton() {
+ somethingChanged= true;
+ try {
+ getButton(APPLY_BUTTON).setEnabled(!getStatus().matches(IStatus.ERROR));
+ } catch (NullPointerException e) {
+ //$FALL-THROUGH$
+ }
+ }
+
+ protected void updateButtonsEnableState(IStatus status) {
+ super.updateButtonsEnableState(status);
+ getButton(APPLY_BUTTON).setEnabled(!status.matches(IStatus.ERROR) && somethingChanged);
+ }
+
+ protected void buttonPressed(int buttonId) {
+ switch (buttonId) {
+ case APPLY_BUTTON:
+ getButton(APPLY_BUTTON).setEnabled(false);
+ somethingChanged= false;
+ //$FALL-THROUGH$
+ case OK:
+ applyChanges();
+ }
+ super.buttonPressed(buttonId);
+ }
+
+ private boolean select(Combo combo, String item) {
+ int index= Arrays.asList(combo.getItems()).indexOf(item);
+ if (index >= 0) {
+ combo.select(index);
+ return true;
+ }
+ return false;
+ }
+
+ private void updateCombos() {
+ final String[] empty= new String[0];
+ try {
+ IType type= fValidator.findType(fBuilderSettings.className);
+ fAppendMethodName.setItems((String[])fValidator.getAppendMethodSuggestions(type).toArray(empty));
+ select(fAppendMethodName, fBuilderSettings.appendMethod);
+ fResultMethodName.setItems((String[])fValidator.getResultMethodSuggestions(type).toArray(empty));
+ select(fResultMethodName, fBuilderSettings.resultMethod);
+ } catch (JavaModelException e1) {
+ fAppendMethodName.setItems(empty);
+ fResultMethodName.setItems(empty);
+ } catch (NullPointerException e1) {
+ fAppendMethodName.setItems(empty);
+ fResultMethodName.setItems(empty);
+ }
+ }
+
+ private void applyChanges() {
+ fBuilderSettings.appendMethod= fAppendMethodName.getText();
+ fBuilderSettings.resultMethod= fResultMethodName.getText();
+ getGenerationSettings().writeCustomBuilderSettings(fBuilderSettings);
+ }
+
+ private Text createTextField(Composite composite, int gridHSpan, String text) {
+ Text result= new Text(composite, SWT.BORDER);
+ result.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, gridHSpan, 1));
+ result.setText(text);
+ result.addModifyListener(modifyListener);
+ TextFieldNavigationHandler.install(result);
+ return result;
+ }
+
+ private void browseForBuilderClass() {
+ try {
+ IJavaSearchScope scope= SearchEngine.createJavaSearchScope(new IJavaElement[] { getType().getJavaProject() });
+ SelectionDialog dialog= JavaUI.createTypeDialog(getShell(), PlatformUI.getWorkbench().getProgressService(), scope,
+ IJavaElementSearchConstants.CONSIDER_CLASSES, false, "*ToString", fExtension); //$NON-NLS-1$
+ dialog.setTitle(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_classSelection_windowTitle);
+ dialog.setMessage(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_classSelection_message);
+ dialog.open();
+ if (dialog.getReturnCode() == OK) {
+ IType type= (IType)dialog.getResult()[0];
+ fBuilderClassName.setText(type.getFullyQualifiedParameterizedName());
+ List suggestions= fValidator.getAppendMethodSuggestions(type);
+ if (!suggestions.contains(fAppendMethodName.getText()))
+ fAppendMethodName.setText((String)suggestions.get(0));
+ suggestions= fValidator.getResultMethodSuggestions(type);
+ if (!suggestions.contains(fResultMethodName.getText()))
+ fResultMethodName.setText((String)suggestions.get(0));
+ }
+ } catch (JavaModelException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
private ToStringGenerationSettings fGenerationSettings;
private static final int DOWN_BUTTON= IDialogConstants.CLIENT_ID + 2;
@@ -750,7 +1207,7 @@
* {@inheritDoc}
*/
public boolean close() {
- fGenerationSettings.writeDialogSettings(getDialogSettings());
+ fGenerationSettings.writeDialogSettings();
fGenerationSettings.stringFormatTemplate= getTemplates(getDialogSettings())[fGenerationSettings.stringFormatTemplateNumber];
@@ -881,6 +1338,8 @@
private Button skipNullsButton;
+ private Button styleButton;
+
protected Composite createCommentSelection(Composite parentComposite) {
Composite composite= super.createCommentSelection(parentComposite);
@@ -889,8 +1348,8 @@
GridLayout groupLayout= new GridLayout();
group.setLayout(groupLayout);
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
-
+
+
Composite composite2= new Composite(group, SWT.NONE);
GridLayout layout= new GridLayout(3, false);
layout.marginWidth= 0;
@@ -927,9 +1386,9 @@
styleLabel.setText(JavaUIMessages.GenerateToStringDialog_code_style_combo);
gridData= new GridData(SWT.FILL, SWT.CENTER, false, false);
styleLabel.setLayoutData(gridData);
-
+
final Combo styleCombo= new Combo(composite2, SWT.READ_ONLY);
- styleCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+ styleCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
styleCombo.setItems(GenerateToStringOperation.getStyleNames());
styleCombo.select(Math.min(fGenerationSettings.toStringStyle, styleCombo.getItemCount() - 1));
SWTUtil.setDefaultVisibleItemCount(styleCombo);
@@ -939,6 +1398,15 @@
}
});
+ styleButton= new Button(composite2, SWT.NONE);
+ styleButton.setText(JavaUIMessages.GenerateToStringDialog_codeStyleConfigureButton);
+ setButtonLayoutData(styleButton);
+ styleButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ configureStyleButtonSelected();
+ }
+ });
+
skipNullsButton= new Button(group, SWT.CHECK);
skipNullsButton.setText(JavaUIMessages.GenerateToStringDialog_skip_null_button);
skipNullsButton.setSelection(fGenerationSettings.skipNulls);
@@ -994,13 +1462,20 @@
formatCombo.select(Math.min(fGenerationSettings.stringFormatTemplateNumber, formatCombo.getItemCount() - 1));
}
+ private void configureStyleButtonSelected() {
+ CustomBuilderConfigurationDialog dialog= new CustomBuilderConfigurationDialog(getShell());
+ dialog.open();
+ updateOKStatus();
+ }
+
private void changeToStringStyle(int style) {
fGenerationSettings.toStringStyle= style;
skipNullsButton.setEnabled(style != GenerateToStringOperation.STRING_FORMAT);
- boolean enableFormat= style != GenerateToStringOperation.APACHE_BUILDER && style != GenerateToStringOperation.APACHE_BUILDER_CHAINED && style != GenerateToStringOperation.SPRING_CREATOR
- && style != GenerateToStringOperation.SPRING_CREATOR_CHAINED;
+ boolean enableFormat= (style != GenerateToStringOperation.CUSTOM_BUILDER);
formatLabel.setEnabled(enableFormat);
formatCombo.setEnabled(enableFormat);
+ styleButton.setEnabled(style == GenerateToStringOperation.CUSTOM_BUILDER);
+ updateOKStatus();
}
}
Index: ui/org/eclipse/jdt/internal/ui/JavaUIMessages.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/JavaUIMessages.java,v
retrieving revision 1.50
diff -u -r1.50 JavaUIMessages.java
--- ui/org/eclipse/jdt/internal/ui/JavaUIMessages.java 30 Mar 2009 13:03:56 -0000 1.50
+++ ui/org/eclipse/jdt/internal/ui/JavaUIMessages.java 17 Apr 2009 14:18:19 -0000
@@ -9,6 +9,7 @@
* IBM Corporation - initial API and implementation
* Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
* Mateusz Matela - [toString] Template edit dialog has usability issues - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267916
+ * Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
*******************************************************************************/
package org.eclipse.jdt.internal.ui;
@@ -91,6 +92,7 @@
public static String GenerateToStringDialog_defaultTemplateName;
public static String GenerateToStringDialog_dialog_title;
public static String GenerateToStringDialog_select_fields_to_include;
+ public static String GenerateToStringDialog_selectioninfo_customBuilderConfigError;
public static String GenerateToStringDialog_selectioninfo_more;
public static String GenerateToStringDialog_methods_node;
public static String GenerateToStringDialog_fields_node;
@@ -99,6 +101,27 @@
public static String GenerateToStringDialog_string_format_combo;
public static String GenerateToStringDialog_manage_templates_button;
public static String GenerateToStringDialog_code_style_combo;
+ public static String GenerateToStringDialog_codeStyleConfigureButton;
+ public static String GenerateToStringDialog_customBuilderConfig_appendMethodField;
+ public static String GenerateToStringDialog_customBuilderConfig_applyButton;
+ public static String GenerateToStringDialog_customBuilderConfig_browseButton;
+ public static String GenerateToStringDialog_customBuilderConfig_builderClassField;
+ public static String GenerateToStringDialog_customBuilderConfig_chainedCallsCheckbox;
+ public static String GenerateToStringDialog_customBuilderConfig_classSelection_message;
+ public static String GenerateToStringDialog_customBuilderConfig_classSelection_windowTitle;
+ public static String GenerateToStringDialog_customBuilderConfig_dataBalidationError;
+ public static String GenerateToStringDialog_customBuilderConfig_invalidAppendMethodError;
+ public static String GenerateToStringDialog_customBuilderConfig_invalidClassError;
+ public static String GenerateToStringDialog_customBuilderConfig_invalidLabelError;
+ public static String GenerateToStringDialog_customBuilderConfig_invalidResultMethodError;
+ public static String GenerateToStringDialog_customBuilderConfig_labelField;
+ public static String GenerateToStringDialog_customBuilderConfig_noAppendMethodError;
+ public static String GenerateToStringDialog_customBuilderConfig_noBuilderClassError;
+ public static String GenerateToStringDialog_customBuilderConfig_noConstructorError;
+ public static String GenerateToStringDialog_customBuilderConfig_noResultMethodError;
+ public static String GenerateToStringDialog_customBuilderConfig_resultMethodField;
+ public static String GenerateToStringDialog_customBuilderConfig_typeValidationError;
+ public static String GenerateToStringDialog_customBuilderConfig_windowTitle;
public static String GenerateToStringDialog_ignore_default_button;
public static String GenerateToStringDialog_limit_elements_button;
public static String GenerateToStringDialog_newTemplateName;
Index: ui/org/eclipse/jdt/internal/ui/JavaUIMessages.properties
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/JavaUIMessages.properties,v
retrieving revision 1.284
diff -u -r1.284 JavaUIMessages.properties
--- ui/org/eclipse/jdt/internal/ui/JavaUIMessages.properties 30 Mar 2009 13:03:56 -0000 1.284
+++ ui/org/eclipse/jdt/internal/ui/JavaUIMessages.properties 17 Apr 2009 14:18:20 -0000
@@ -9,6 +9,7 @@
# IBM Corporation - initial API and implementation
# Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
# Mateusz Matela - [toString] Template edit dialog has usability issues - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267916
+# Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
###############################################################################
JavaPlugin_additionalInfo_affordance=Press 'Tab' from proposal table or click for focus
@@ -85,6 +86,7 @@
GenerateToStringDialog_templateEdition_WindowTitle=Edit template
GenerateToStringDialog_templateManagerApplyButton=&Apply
GenerateToStringDialog_templateManagerNoTemplateErrorMessage=There must be at least one template.
+GenerateToStringDialog_selectioninfo_customBuilderConfigError=Custom toString() builder is not configured properly.
GenerateToStringDialog_selectioninfo_more={0} of {1} fields and {2} of {3} methods selected.
GenerateToStringDialog_methods_node=Methods
GenerateToStringDialog_fields_node=Fields
@@ -93,6 +95,27 @@
GenerateToStringDialog_string_format_combo=String &format:
GenerateToStringDialog_manage_templates_button=&Edit...
GenerateToStringDialog_code_style_combo=C&ode style:
+GenerateToStringDialog_codeStyleConfigureButton=Con&figure...
+GenerateToStringDialog_customBuilderConfig_appendMethodField=&Append method:
+GenerateToStringDialog_customBuilderConfig_applyButton=A&pply
+GenerateToStringDialog_customBuilderConfig_browseButton=Bro&wse...
+GenerateToStringDialog_customBuilderConfig_builderClassField=&Builder class:
+GenerateToStringDialog_customBuilderConfig_chainedCallsCheckbox=&Chain invocations
+GenerateToStringDialog_customBuilderConfig_classSelection_message=Choose the toString() builder class:
+GenerateToStringDialog_customBuilderConfig_classSelection_windowTitle=Builder Class Selection
+GenerateToStringDialog_customBuilderConfig_dataBalidationError=Error while walidating entered data
+GenerateToStringDialog_customBuilderConfig_invalidAppendMethodError=There are no methods named "{0}" that can be used as append methods in selected class.
+GenerateToStringDialog_customBuilderConfig_invalidClassError="{0}" class does not exist. Configuration is invalid.
+GenerateToStringDialog_customBuilderConfig_invalidLabelError="{0}" cannot be used as a label for toString() builder.
+GenerateToStringDialog_customBuilderConfig_invalidResultMethodError=There''s no method named "{0}" that can be used as a result method in selected class.
+GenerateToStringDialog_customBuilderConfig_labelField=Builder &label:
+GenerateToStringDialog_customBuilderConfig_noAppendMethodError=Selected type must provide methods that can be used to append objects (e.g. a method taking a signle Object argument).
+GenerateToStringDialog_customBuilderConfig_noBuilderClassError=Builder class field shouldn't be empty. Configuration is invalid.
+GenerateToStringDialog_customBuilderConfig_noConstructorError=Selected type must provide a constructor that takes a single object.
+GenerateToStringDialog_customBuilderConfig_noResultMethodError=Selected type must provide a method that can be used to retrieve result (i.e. taking no arguments and returning String)
+GenerateToStringDialog_customBuilderConfig_resultMethodField=&Result method:
+GenerateToStringDialog_customBuilderConfig_typeValidationError=Could not validate selected type.
+GenerateToStringDialog_customBuilderConfig_windowTitle=Configure Custom toString() Builder
GenerateToStringDialog_ignore_default_button=&List contents of arrays instead of using native toString()
GenerateToStringDialog_limit_elements_button=Li&mit number of items in arrays/collections/maps to
GenerateToStringDialog_skip_null_button=Skip &null values
Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/CustomBuilderGenerator.java
===================================================================
RCS file: core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/CustomBuilderGenerator.java
diff -N core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/CustomBuilderGenerator.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/tostringgeneration/CustomBuilderGenerator.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Mateusz Matela and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mateusz Matela - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070
+ * Mateusz Matela - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.NamingConventions;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.IfStatement;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.StringLiteral;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+import org.eclipse.jdt.core.dom.InfixExpression.Operator;
+
+import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationMessages;
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+
+
+/**
+ *
+ * Implementation of AbstractToStringGenerator
that creates toString()
+ * method using external library. The library must deliver a string builder , that is a class that
+ * fulfills following requirements:
+ *
+ * - Provides a constructor taking single Object
+ * - Provides methods for appending objects. There may many such methods (with the same name, for
+ * example
append(...)
), but there must be at least a version that takes single Object
+ * or an Object and a String (in any order). These methods should return builder object, otherwise
+ * generator will not be able to make call chains.
+ * - Provides a result method (usually
toString()
), that is a method that takes no
+ * arguments and returns a Strinig
+ *
+ *
+ *
+ * Generated methods look like this:
+ *
+ *
+ * public String toString() {
+ * ExternalBuilder builder= new ExternalBuilder();
+ * builder.append("field1", field1);
+ * builder.append("field2", field2);
+ * return builder.toString();
+ * }
+ *
+ *
+ *
+ *
+ * @since 3.5
+ */
+public class CustomBuilderGenerator extends AbstractToStringGenerator {
+
+ private final List primitiveTypes= Arrays.asList(new String[] { "byte", "short", "char", "int", "long", "float", "double", "boolean" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
+
+ private final String[] wrapperTypes= new String[] { "java.lang.Byte", "java.lang.Short", "java.lang.Character", "java.lang.Integer", "java.lang.Long", "java.lang.Float", "java.lang.Double", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+ "java.lang.Boolean" }; //$NON-NLS-1$
+
+ /**
+ * true, if the last expression created with {@link #createAppendMethodForMember(Object)}
+ * returns builder type and therefore can be used to chain calls
+ **/
+ private boolean canChainLastAppendCall;
+
+ /**
+ * Class for storing information about versions of append method in the builder class that can
+ * be used for different member types
+ */
+ private class AppendMethodInformation {
+ /**
+ * Type of method in raltion to taken parameter types. Possible values:
+ *
+ * - method takes one type parameter
+ * - method takes one type parameter and one string
+ * - method takes one string and one type parameter
+ *
+ */
+ public int methodType;
+
+ /**
+ * true if method returns the builder class object so it can be used to form chains of calls
+ **/
+ public boolean returnsBuilder;
+ }
+
+ /**
+ * Information about versions of append method in the builder type
+ *
+ * key: String - fully qualified name of a member type
+ *
+ * value: {@link AppendMethodInformation} - information about corresponding method
+ */
+ private HashMap appendMethodSpecificTypes= new HashMap();
+
+ public RefactoringStatus checkConditions() {
+ RefactoringStatus status= super.checkConditions();
+ if (fContext.isCustomArray() || fContext.isLimitItems())
+ status.addWarning(CodeGenerationMessages.GenerateToStringOperation_warning_no_arrays_collections_with_this_style);
+ return status;
+ }
+
+ protected void addElement(Object element) {
+ }
+
+ protected void initialize() {
+ super.initialize();
+
+ fillAppendMethodsMap();
+
+ tidyAppendsMethodsMap();
+ }
+
+ public MethodDeclaration generateToStringMethod() throws CoreException {
+ initialize();
+
+ //ToStringBuilder builder= new ToStringBuilder(this);
+ String builderVariableName= createNameSuggestion(getContext().getCustomBuilderLabel(), NamingConventions.VK_LOCAL);
+ VariableDeclarationFragment fragment= fAst.newVariableDeclarationFragment();
+ fragment.setName(fAst.newSimpleName(builderVariableName));
+ ClassInstanceCreation classInstance= fAst.newClassInstanceCreation();
+ String typeName= addImport(getContext().getCustomBuilderClass());
+ classInstance.setType(fAst.newSimpleType(fAst.newSimpleName(typeName)));
+ classInstance.arguments().add(fAst.newThisExpression());
+ fragment.setInitializer(classInstance);
+ VariableDeclarationStatement vStatement= fAst.newVariableDeclarationStatement(fragment);
+ vStatement.setType(fAst.newSimpleType(fAst.newName(typeName)));
+ toStringMethod.getBody().statements().add(vStatement);
+
+ /* expression for accumulating chained calls */
+ Expression expression= null;
+
+ for (int i= 0; i < getContext().getSelectedMembers().length; i++) {
+ //builder.append("member", member);
+ MethodInvocation appendInvocation= createAppendMethodForMember(getContext().getSelectedMembers()[i]);
+ if (getContext().isSkipNulls() && !getMemberType(getContext().getSelectedMembers()[i]).isPrimitive()) {
+ if (expression != null) {
+ toStringMethod.getBody().statements().add(fAst.newExpressionStatement(expression));
+ expression= null;
+ }
+ appendInvocation.setExpression(fAst.newSimpleName(builderVariableName));
+ IfStatement ifStatement= fAst.newIfStatement();
+ ifStatement.setExpression(createInfixExpression(createMemberAccessExpression(getContext().getSelectedMembers()[i], true, true), Operator.NOT_EQUALS, fAst.newNullLiteral()));
+ ifStatement.setThenStatement(createOneStatementBlock(appendInvocation));
+ toStringMethod.getBody().statements().add(ifStatement);
+ } else {
+ if (expression != null) {
+ appendInvocation.setExpression(expression);
+ } else {
+ appendInvocation.setExpression(fAst.newSimpleName(builderVariableName));
+ }
+ if (getContext().isCustomBuilderChainedCalls() && canChainLastAppendCall) {
+ expression= appendInvocation;
+ } else {
+ expression= null;
+ toStringMethod.getBody().statements().add(fAst.newExpressionStatement(appendInvocation));
+ }
+ }
+ }
+
+ if (expression != null) {
+ toStringMethod.getBody().statements().add(fAst.newExpressionStatement(expression));
+ }
+ // return builder.toString();
+ ReturnStatement rStatement= fAst.newReturnStatement();
+ rStatement.setExpression(createMethodInvocation(builderVariableName, getContext().getCustomBuilderResultMethod(), null));
+ toStringMethod.getBody().statements().add(rStatement);
+
+ complete();
+
+ return toStringMethod;
+ }
+
+ /**
+ * Searches through methods with proper name and for each argument type
+ * remembers the best option
+ */
+ private void fillAppendMethodsMap() {
+ try {
+ IJavaProject javaProject= getContext().getTypeBinding().getJavaElement().getJavaProject();
+ IType type= javaProject.findType(getContext().getCustomBuilderClass());
+ IType[] types= type.newSupertypeHierarchy(null).getAllClasses();
+ for (int i= 0; i < types.length; i++) {
+ IMethod[] methods= types[i].getMethods();
+ for (int j= 0; j < methods.length; j++) {
+ if (!Flags.isPublic(methods[j].getFlags()) || !methods[j].getElementName().equals(getContext().getCustomBuilderAppendMethod()))
+ continue;
+ String[] parameterTypes= methods[j].getParameterTypes();
+ AppendMethodInformation appendMethodInformation= new AppendMethodInformation();
+ String specyficType;
+ if (parameterTypes.length == 1) {
+ specyficType= JavaModelUtil.getResolvedTypeName(parameterTypes[0], types[i]);
+ appendMethodInformation.methodType= 1;
+ } else if (parameterTypes.length == 2) {
+ String resolvedParameterTypeName1= JavaModelUtil.getResolvedTypeName(parameterTypes[0], types[i]);
+ String resolvedParameterTypeName2= JavaModelUtil.getResolvedTypeName(parameterTypes[1], types[i]);
+ if (resolvedParameterTypeName1.equals("java.lang.String")) {//$NON-NLS-1$
+ specyficType= resolvedParameterTypeName2;
+ appendMethodInformation.methodType= 3;
+ } else if (resolvedParameterTypeName2.equals("java.lang.String")) {//$NON-NLS-1$
+ specyficType= resolvedParameterTypeName1;
+ appendMethodInformation.methodType= 2;
+ } else
+ continue;
+ } else
+ continue;
+
+ appendMethodInformation.returnsBuilder= getContext().getCustomBuilderClass().equals(JavaModelUtil.getResolvedTypeName(methods[j].getReturnType(), types[i]));
+
+ AppendMethodInformation oldAMI= (AppendMethodInformation)appendMethodSpecificTypes.get(specyficType);
+ if (oldAMI == null || oldAMI.methodType < appendMethodInformation.methodType) {
+ appendMethodSpecificTypes.put(specyficType, appendMethodInformation);
+ }
+ }
+ }
+ } catch (JavaModelException e) {
+ throw new RuntimeException("couldn't initialize custom toString() builder generator", e); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Removes information about types from {@link #appendMethodSpecificTypes} if their
+ * parametersType is worse than for java.lang.Object.
+ */
+ private void tidyAppendsMethodsMap() {
+ int objectParametersType= ((AppendMethodInformation)appendMethodSpecificTypes.get("java.lang.Object")).methodType; //$NON-NLS-1$
+ Set entrySet= appendMethodSpecificTypes.entrySet();
+ for (Iterator iterator= entrySet.iterator(); iterator.hasNext();) {
+ Map.Entry entry= (Map.Entry)iterator.next();
+ if (((AppendMethodInformation)entry.getValue()).methodType < objectParametersType) {
+ iterator.remove();
+ }
+ }
+ }
+
+ private MethodInvocation createAppendMethodForMember(Object member) {
+ ITypeBinding memberType= getMemberType(member);
+ String memberTypeName= memberType.getQualifiedName();
+
+ Expression memberAccessExpression= null;
+
+ AppendMethodInformation ami= (AppendMethodInformation)appendMethodSpecificTypes.get(memberTypeName);
+ if (ami == null) {
+ ami= (AppendMethodInformation)appendMethodSpecificTypes.get("java.lang.Object");//$NON-NLS-1$
+ if (memberType.isPrimitive() && !getContext().is50orHigher()) {
+ String nonPrimitiveType= wrapperTypes[primitiveTypes.indexOf(memberTypeName)];
+ ClassInstanceCreation classInstance= fAst.newClassInstanceCreation();
+ classInstance.setType(fAst.newSimpleType(fAst.newSimpleName(addImport(nonPrimitiveType))));
+ classInstance.arguments().add(createMemberAccessExpression(member, true, true));
+ memberAccessExpression= classInstance;
+ }
+ }
+ if (memberAccessExpression == null) {
+ memberAccessExpression= createMemberAccessExpression(member, false, getContext().isSkipNulls());
+ }
+
+ MethodInvocation appendInvocation= fAst.newMethodInvocation();
+ appendInvocation.setName(fAst.newSimpleName(getContext().getCustomBuilderAppendMethod()));
+ if (ami.methodType == 1 || ami.methodType == 2) {
+ appendInvocation.arguments().add(memberAccessExpression);
+ }
+ if (ami.methodType == 2 || ami.methodType == 3) {
+ StringLiteral literal= fAst.newStringLiteral();
+ literal.setLiteralValue(getMemberName(member, ToStringTemplateParser.MEMBER_NAME_PARENTHESIS_VARIABLE));
+ appendInvocation.arguments().add(literal);
+ }
+ if (ami.methodType == 3) {
+ appendInvocation.arguments().add(memberAccessExpression);
+ }
+
+ canChainLastAppendCall= ami.returnsBuilder;
+
+ return appendInvocation;
+ }
+}