/* * Copyright 2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sun.tools.xjc.addon.commons_lang; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.xml.sax.ErrorHandler; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JExpr; import com.sun.codemodel.JExpression; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMod; import com.sun.codemodel.JVar; import com.sun.tools.xjc.BadCommandLineException; import com.sun.tools.xjc.Options; import com.sun.tools.xjc.Plugin; import com.sun.tools.xjc.outline.ClassOutline; import com.sun.tools.xjc.outline.Outline; /** * Automatically generates the toString(), hashCode() and equals() methods * using Jakarta's commons-lang. * <p> * Supports the optional ToStringStyle command line parameter to specify * the style for use within the toString method. * <p> * <pre> * Example 1: * * -Xcommons-lang * -Xcommons-lang:ToStringStyle=SIMPLE_STYLE * * to specify the use of * * org.apache.commons.lang.builder.ToStringStyle.SIMPLE_STYLE * * Example 2: * * -Xcommons-lang * -Xcommons-lang:ToStringStyle=my.CustomToStringStyle * * to specify the use of * * my.CustomToStringStyle, which must be a subclass of * * org.apache.commons.lang.builder.ToStringStyle, and contains a public no-arg constructor. * * </pre> * <p> * The default ToStringStyle adopted by this plugin is MULTI_LINE_STYLE. * * @see org.apache.commons.lang.builder.ToStringStyle * @author Hanson Char */ public class XjcCommonsLangPlugin extends Plugin { private static final String TOSTRING_STYLE_PARAM = "-Xcommons-lang:ToStringStyle="; private String toStringStyle = "MULTI_LINE_STYLE"; private Class<?> customToStringStyle; @Override public String getOptionName() { return "Xcommons-lang"; } @Override public String getUsage() { return " -Xcommons-lang : generate toString(), hashCode() and equals() for generated code using Jakarta's common-lang\n" + " [-Xcommons-lang:ToStringStyle=MULTI_LINE_STYLE\n\t" + "| DEFAULT_STYLE\n\t" + "| NO_FIELD_NAMES_STYLE\n\t" + "| SHORT_PREFIX_STYLE\n\t" + "| SIMPLE_STYLE\n\t" + "| <Fully qualified class name of a ToStringStyle subtype>]\n" ; } @Override public boolean run(Outline outline, @SuppressWarnings("unused") Options opt, @SuppressWarnings("unused") ErrorHandler errorHandler) { // Process every pojo class generated by jaxb for (ClassOutline classOutline : outline.getClasses()) { JDefinedClass implClass = classOutline.implClass; this.createToStringMethod(implClass); this.createEqualsMethod(implClass); this.createHashCodeMethod(implClass); } return true; } private void createToStringMethod(JDefinedClass implClass) { JCodeModel codeModel = implClass.owner(); JMethod toStringMethod = implClass.method(JMod.PUBLIC, codeModel.ref(String.class), "toString"); // Annotate with @Override toStringMethod.annotate(Override.class); final JExpression toStringStyleExpr = customToStringStyle == null ? codeModel.ref(ToStringStyle.class) .staticRef(toStringStyle) : JExpr._new( codeModel.ref(customToStringStyle)) ; // Invoke ToStringBuilder.reflectionToString(Object,StringStyle) toStringMethod.body() ._return( codeModel.ref(ToStringBuilder.class) .staticInvoke("reflectionToString") .arg(JExpr._this()) .arg(toStringStyleExpr) ); return; } private void createEqualsMethod(JDefinedClass implClass) { JCodeModel codeModel = implClass.owner(); JMethod toStringMethod = implClass.method(JMod.PUBLIC, codeModel.BOOLEAN, "equals"); JVar that = toStringMethod.param(Object.class, "that"); // Annotate with @Override toStringMethod.annotate(Override.class); // Invoke EqualsBuilder.reflectionEquals(Object,Object); toStringMethod.body()._return( codeModel.ref(EqualsBuilder.class) .staticInvoke("reflectionEquals") .arg(JExpr._this()) .arg(that) ); return; } private void createHashCodeMethod(JDefinedClass implClass) { JCodeModel codeModel = implClass.owner(); JMethod toStringMethod = implClass.method(JMod.PUBLIC, codeModel.INT, "hashCode"); // Annotate with @Override toStringMethod.annotate(Override.class); // Invoke EqualsBuilder.reflectionHashCode(Object); toStringMethod.body()._return( codeModel.ref(HashCodeBuilder.class) .staticInvoke("reflectionHashCode") .arg(JExpr._this()) ); return; } @Override public int parseArgument(Options opt, String[] args, int i) throws BadCommandLineException { // eg. -Xcommons-lang ToStringStyle=SIMPLE_STYLE String arg = args[i].trim(); if (arg.startsWith(TOSTRING_STYLE_PARAM)) { toStringStyle = arg.substring(TOSTRING_STYLE_PARAM.length()); try { ToStringStyle.class.getField(toStringStyle); return 1; } catch (SecurityException e) { throw new BadCommandLineException(e.getMessage()); } catch (NoSuchFieldException ignore) { } try { customToStringStyle = Class.forName(toStringStyle); } catch (ClassNotFoundException e) { throw new BadCommandLineException(e.getMessage()); } return 1; } return 0; } }