Hi Dan,
The patch is attached. Let me know if you prefer that I open a Jira
issue to submit it.
Regards,
Simon
2012/9/4 Daniel Kulp <[email protected]>:
>
> Would you consider submitting a patch to the CXF ts plugin that enables this?
>
> We currently have a few "styles" that can be selected via:
> -Xts:style:simple
> -Xts:style:mulitline
>
> We could definitely add a:
> -Xts:style:guava
>
> or similar that would do this.
>
> Dan
>
>
>
> On Sep 1, 2012, at 4:17 AM, Simon <[email protected]> wrote:
>
>> Thank you for your answer Glen. I missed this plugin in my search.
>>
>> Though this plugin offers a lot of flexibility, it generates too much
>> code for my needs.
>>
>> In the meantime, I tried to make my own plugin which appear to be
>> quite simple. As I was inspired by the cxf-xjc-ts plugin, I post it
>> here so anyone can use it :
>>
>> package com.package;
>>
>> import java.util.logging.Logger;
>> import org.xml.sax.*;
>> import com.sun.codemodel.*;
>> import com.sun.tools.xjc.*;
>> import com.sun.tools.xjc.outline.*;
>>
>> /**
>> * @author Simon B.
>> */
>> public class ToStringPlugin extends Plugin {
>>
>> private static final Logger LOG =
>> Logger.getLogger(ToStringPlugin.class.getName());
>>
>> private static final String NAME = "toString() XJC Plugin";
>>
>> @Override
>> public String getOptionName() {
>> return "Xto-string";
>> }
>>
>> @Override
>> public String getUsage() {
>> return "-Xto-string : Activate plugin to add a toString()
>> method to
>> generated classes.";
>> }
>>
>> @Override
>> public boolean run(Outline outline, Options opt, ErrorHandler
>> errorHandler) throws SAXException {
>> LOG.fine("Running " + NAME + ".");
>>
>> JClass guavaObjects =
>> outline.getCodeModel().ref("com.google.common.base.Objects");
>>
>> for (ClassOutline co : outline.getClasses()) {
>> addToStringMethod(co, guavaObjects);
>> }
>>
>> return true;
>> }
>>
>> private void addToStringMethod(ClassOutline co, JClass guavaObjects) {
>>
>> JDefinedClass implementation = co.implClass;
>>
>> //
>> // Create toString() method
>> //
>> JMethod toStringMethod = implementation.method(JMod.PUBLIC,
>> String.class, "toString");
>>
>> JDocComment doc = toStringMethod.javadoc();
>> doc.add("Generated by " + NAME);
>> toStringMethod.annotate(Override.class);
>>
>> //
>> // return Objects.toStringHelper(this)
>> // .add("propertyName0", propertyValue0)
>> // ...
>> // .add("propertyNameN", propertyValueN)
>> // .toString();
>> //
>>
>> JInvocation toStringHelperInvocation =
>> guavaObjects.staticInvoke("toStringHelper");
>> toStringHelperInvocation.arg(JExpr._this());
>>
>> JInvocation lastAddInvocation = toStringHelperInvocation;
>> for (JFieldVar var : implementation.fields().values()) {
>> if (isStatic(var.mods()) == false) {
>> JInvocation addInvocation =
>> JExpr.invoke(lastAddInvocation, "add");
>> addInvocation.arg(JExpr.lit(var.name()));
>> addInvocation.arg(JExpr.ref(var.name()));
>> lastAddInvocation = addInvocation;
>> }
>> }
>>
>> JInvocation toStringInvocation =
>> JExpr.invoke(lastAddInvocation, "toString");
>>
>> toStringMethod.body()._return(toStringInvocation);
>>
>> }
>>
>> private static boolean isStatic(JMods mods) {
>> return (mods.getValue() & JMod.STATIC) != 0;
>> }
>>
>> }
>>
>>
>>
>>
>>
>> 2012/8/31 Glen Mazza <[email protected]>:
>>> Hi Simon, I haven't done this before, but the alternative ToString plugin
>>> (http://confluence.highsource.org/display/J2B/ToString+plugin) has a
>>> "-XtoString-toStringStrategyClass" option where you can apparently make up
>>> whatever toString() format you desire. This blog entry:
>>> http://www.jroller.com/gmazza/entry/enhancing_jaxb_artifacts#Plugin can show
>>> you how to use the plugin itself, but creating the toString() strategy
>>> itself may require some googling of source code to find out the process.
>>>
>>> HTH,
>>> Glen
>>>
>>>
>>> On 08/31/2012 06:09 AM, Simon wrote:
>>>>
>>>> Hi !
>>>>
>>>> I'am using CXF (2.6.1) for my projects and I would like to have a
>>>> toString() method for our generated JAXB classes.
>>>>
>>>> I'am using Maven as the build system.
>>>>
>>>> The easier solution seems to use the 'cxf-codegen-plugin' in
>>>> combination with the 'toString() XJC Plugin' like this :
>>>>
>>>> <plugin>
>>>> <groupId>org.apache.cxf</groupId>
>>>> <artifactId>cxf-codegen-plugin</artifactId>
>>>> <version>2.6.1</version>
>>>> <dependencies>
>>>> <dependency>
>>>> <groupId>org.apache.cxf.xjcplugins</groupId>
>>>> <artifactId>cxf-xjc-ts</artifactId>
>>>> <version>2.6.0</version>
>>>> </dependency>
>>>> </dependencies>
>>>> <configuration>
>>>> <defaultOptions>
>>>> <extraargs>
>>>>
>>>> <extraarg>-xjc-Xts:style:org.apache.commons.lang.builder.ToStringStyle.SIMPLE_STYLE</extraarg>
>>>> </extraargs>
>>>> </defaultOptions>
>>>> </configuration>
>>>> <executions>
>>>> <execution>
>>>> <id>generate-sources</id>
>>>> <goals>
>>>> <goal>wsdl2java</goal>
>>>> </goals>
>>>> </execution>
>>>> </executions>
>>>> </plugin>
>>>>
>>>> This will generate this :
>>>>
>>>> @Override
>>>> public String toString() {
>>>> return ToStringBuilder.reflectionToString(this,
>>>> ToStringStyle.SIMPLE_STYLE);
>>>> }
>>>>
>>>> However, as my projects are all using Guava, I would prefere to
>>>> generate the toString() method this way :
>>>>
>>>> @Override
>>>> public String toString() {
>>>> return Objects.toStringHelper(this)
>>>> .add("name", name)
>>>> .add("phone", phone)
>>>> .add("eMail", eMail)
>>>> .add("fax", fax)
>>>> .toString();
>>>> }
>>>>
>>>> Is there a plan to add this feature (using Guava) in the existing XJC
>>>> Plugin ?
>>>>
>>>> Thank you !
>>>
>>>
>>>
>>> --
>>> Glen Mazza
>>> Talend Community Coders - coders.talend.com
>>> blog: www.jroller.com/gmazza
>>>
>
> --
> Daniel Kulp
> [email protected] - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
>
Index: ts/src/main/java/org/apache/cxf/xjc/ts/ToStringPlugin.java
===================================================================
--- ts/src/main/java/org/apache/cxf/xjc/ts/ToStringPlugin.java (revision
1382247)
+++ ts/src/main/java/org/apache/cxf/xjc/ts/ToStringPlugin.java (working copy)
@@ -29,9 +29,11 @@
import com.sun.codemodel.JDocComment;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JFieldRef;
+import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
+import com.sun.codemodel.JMods;
import com.sun.tools.xjc.BadCommandLineException;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.outline.ClassOutline;
@@ -63,6 +65,7 @@
+ " -Xts:style:simple : Have toString produce single line
terse output\n"
+ " equivalent to: "
+
"-Xts:style:org.apache.cxf.xjc.runtime.JAXBToStringStyle.SIMPLE_STYLE\n"
+ + " -Xts:style:guava : Have toString produced by the Guava
library\n"
+ "
-Xts:style:org.apache.commons.lang.builder.ToStringStyle.FIELD : The full
class+field\n"
+ " name of the ToStringStyle to use.";
}
@@ -78,7 +81,9 @@
if ("multiline".equals(v)) {
styleFieldName = "MULTI_LINE_STYLE";
} else if ("simple".equals(v)) {
- styleFieldName = "SIMPLE_STYLE";
+ styleFieldName = "SIMPLE_STYLE";
+ } else if ("guava".equals(v)) {
+ styleFieldName = "GUAVA_STYLE";
} else {
int idx = v.lastIndexOf('.');
styleFieldName = v.substring(idx + 1);
@@ -99,13 +104,24 @@
return true;
}
- final JClass toStringDelegateImpl = outline.getCodeModel()
- .ref("org.apache.commons.lang.builder.ToStringBuilder");
+ boolean guavaStyle = "GUAVA_STYLE".equals(styleFieldName);
+ final JClass toStringDelegateImpl;
+ if (guavaStyle) {
+ toStringDelegateImpl = outline.getCodeModel()
+ .ref("com.google.common.base.Objects");
+ } else {
+ toStringDelegateImpl = outline.getCodeModel()
+ .ref("org.apache.commons.lang.builder.ToStringBuilder");
+ }
final JClass styleClass = outline.getCodeModel().ref(styleClassName);
final JFieldRef toStringDelegateStyleParam =
styleClass.staticRef(styleFieldName);
for (ClassOutline co : outline.getClasses()) {
- addToStringMethod(co, toStringDelegateImpl,
toStringDelegateStyleParam);
+ if (guavaStyle) {
+ addGuavaToStringMethod(co, toStringDelegateImpl);
+ } else {
+ addToStringMethod(co, toStringDelegateImpl,
toStringDelegateStyleParam);
+ }
}
return true;
@@ -116,18 +132,58 @@
JFieldRef toStringDelegateStyleParam) {
final JDefinedClass implementation = co.implClass;
- final JMethod toStringMethod = implementation.method(JMod.PUBLIC,
String.class, "toString");
+ final JMethod toStringMethod = createToStringMethod(implementation);
final JInvocation invoke =
delegateImpl.staticInvoke("reflectionToString");
invoke.arg(JExpr._this());
invoke.arg(toStringDelegateStyleParam);
toStringMethod.body()._return(invoke);
-
+ }
+
+ private JMethod createToStringMethod(JDefinedClass implementation) {
+ final JMethod toStringMethod = implementation.method(JMod.PUBLIC,
String.class, "toString");
JDocComment doc = toStringMethod.javadoc();
doc.add("Generates a String representation of the contents of this
type.");
doc.add("\nThis is an extension method, produced by the 'ts' xjc
plugin");
toStringMethod.annotate(Override.class);
+ return toStringMethod;
}
+
+ private void addGuavaToStringMethod(ClassOutline co, JClass guavaObjects) {
+ final JDefinedClass implementation = co.implClass;
+
+ final JMethod toStringMethod = createToStringMethod(implementation);
+
+ //
+ // return Objects.toStringHelper(this)
+ // .add("propertyName0", propertyValue0)
+ // ...
+ // .add("propertyNameN", propertyValueN)
+ // .toString();
+ //
+
+ final JInvocation toStringHelperInvocation =
guavaObjects.staticInvoke("toStringHelper");
+ toStringHelperInvocation.arg(JExpr._this());
+
+ JInvocation lastAddInvocation = toStringHelperInvocation;
+ for (JFieldVar var : implementation.fields().values()) {
+ if (!isStatic(var.mods())) {
+ JInvocation addInvocation = JExpr.invoke(lastAddInvocation,
"add");
+ addInvocation.arg(JExpr.lit(var.name()));
+ addInvocation.arg(JExpr.ref(var.name()));
+ lastAddInvocation = addInvocation;
+ }
+ }
+
+ JInvocation toStringInvocation = JExpr.invoke(lastAddInvocation,
"toString");
+
+ toStringMethod.body()._return(toStringInvocation);
+ }
+
+ private static boolean isStatic(JMods mods) {
+ return (mods.getValue() & JMod.STATIC) != 0;
+ }
+
public void onActivated(Options opts) {
active = true;
}