EXAMPLES INDEX:
Hello.java
- Simplest possible example that generates a default value object containing a hello message.
SimpleInterfaceWithNamedOutput.java
- Example that shows how to control the name of the generated implementation class.
MutablePair.java
- Example that shows how to generate a simple mutable pair class.
ImmutablePair.java
- Example that shows how to generate a simple immutable pair class.
SerializablePosition.java
- Example that shows how to specify serialization ID for serialiable classes.
ExternalizablePosition.java
- Example that shows how to get an auto-implementation of externalizable.
ExtendingByInheritance.java
- Example that shows how use standard subclassing for customization.
ComparableName.java
- Example that shows how to make generated class implement comparable in a specific way.
package-info.java
- Example of how to configure ValjoGen defaults for interfaces in a package.
JsonWithJackson.java
- Example that shows how to generate a mutable or immutable class with Jackson annotations, so it can be easily converted to/from JSON.
CustomHashCode.java
- Example that shows how to apply a custom template to change the generated code for known methods.
CustomLogginngWithRegions.java
- Example that shows how to apply a simple custom template to provide constructor logging by overriding existing regions.
SimpleCustomMethod.java
- Example that shows how to apply a basic custom template implementing a simple custom method.
AdvancedCustomDigestMethod.java
- Example that shows a non-trivial custom template implementing an advanced custom method that calculate a digest of object state.
BaseClass.java
- Example of a preexisting base class that generated code can extend from.
DigestBaseClass.java
- Example of a preexisting abstract base class that a generated class can extend from.
advanced_custom_method.stg
- This custom template shows how to implement a non-trivial custom method declared in the interface that iterate through all members of the class.
custom_hashCode.stg
- This custom template shows how to add caching to the generated hashCode method.
custom_logging.stg
- This custom template shows how to add logging of created instances to a generated class.
simple_custom_method.stg
- This custom template shows how to implement a custom method declared in the interface.
Hello.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.*; /** * Simplest possible example that generates a default value object containing a hello message. * * NOTE: Comments are entirely optional but used for the websites documentation backend. */ @VALJOGenerate(comment="Example 1") public interface Hello { public String getHelloMessage(); }
Hello.java
=> HelloImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.Hello") public final class HelloImpl implements Hello { private final String helloMessage; public static HelloImpl valueOf(final String helloMessage) { HelloImpl _instance = new HelloImpl(helloMessage); return _instance; } private HelloImpl(final String helloMessage) { super(); this.helloMessage=Objects.requireNonNull(helloMessage); } /** * {@inheritDoc} */ @Override public String getHelloMessage() { return helloMessage; } /** * {@inheritDoc} */ @Override public int hashCode() { int _result = Objects.hash(helloMessage); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") HelloImpl _other = (HelloImpl) arg0; return (Objects.equals(helloMessage, _other.helloMessage)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("HelloImpl ["); _sb.append("helloMessage="); _sb.append(helloMessage); _sb.append(']'); return _sb.toString(); } }
SimpleInterfaceWithNamedOutput.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows how to control the name of the generated implementation class. */ @VALJOGenerate(name="SimpleInterfaceImpl", comment="Example 2") public interface SimpleInterfaceWithNamedOutput { public Object getObject(); public String getString(); }
SimpleInterfaceWithNamedOutput.java
=> SimpleInterfaceImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.SimpleInterfaceWithNamedOutput") public final class SimpleInterfaceImpl implements SimpleInterfaceWithNamedOutput { private final Object object; private final String string; public static SimpleInterfaceImpl valueOf(final Object object, final String string) { SimpleInterfaceImpl _instance = new SimpleInterfaceImpl(object, string); return _instance; } private SimpleInterfaceImpl(final Object object, final String string) { super(); this.object=Objects.requireNonNull(object); this.string=Objects.requireNonNull(string); } /** * {@inheritDoc} */ @Override public Object getObject() { return object; } /** * {@inheritDoc} */ @Override public String getString() { return string; } /** * {@inheritDoc} */ @Override public int hashCode() { int _result = Objects.hash(object, string); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") SimpleInterfaceImpl _other = (SimpleInterfaceImpl) arg0; return (Objects.equals(object, _other.object) && Objects.equals(string, _other.string)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("SimpleInterfaceImpl ["); _sb.append("object="); _sb.append(object); _sb.append(", "); _sb.append("string="); _sb.append(string); _sb.append(']'); return _sb.toString(); } }
MutablePair.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.*; import com.fortyoneconcepts.valjogen.annotations.types.Mutability; /** * Example that shows how to generate a simple mutable pair class. * Note the tiny difference compared to the immutable pair class example. * * @param <TLeft> First object type in pair. * @param <TRight> Second object type in pair. */ @VALJOGenerate(comment="Example 3") @VALJOConfigure(mutability=Mutability.Mutable) public interface MutablePair<TLeft, TRight> { public TLeft getLeft(); public void setLeft(TLeft left); public TRight getRight(); public void setRight(TRight right); }
MutablePair.java
=> MutablePairImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.MutablePair<TLeft,TRight>") public final class MutablePairImpl<TLeft,TRight> implements MutablePair<TLeft,TRight> { private TLeft left; private TRight right; public static <TLeft,TRight> MutablePairImpl<TLeft,TRight> valueOf(final TLeft left, final TRight right) { MutablePairImpl<TLeft,TRight> _instance = new MutablePairImpl<TLeft,TRight>(left, right); return _instance; } public static <TLeft,TRight> MutablePairImpl<TLeft,TRight> valueOf() { MutablePairImpl<TLeft,TRight> _instance = new MutablePairImpl<TLeft,TRight>(); return _instance; } private MutablePairImpl(final TLeft left, final TRight right) { super(); this.left=Objects.requireNonNull(left); this.right=Objects.requireNonNull(right); } private MutablePairImpl() { super(); } /** * {@inheritDoc} */ @Override public TLeft getLeft() { return left; } /** * {@inheritDoc} */ @Override public void setLeft(final TLeft left) { this.left=Objects.requireNonNull(left); } /** * {@inheritDoc} */ @Override public TRight getRight() { return right; } /** * {@inheritDoc} */ @Override public void setRight(final TRight right) { this.right=Objects.requireNonNull(right); } /** * {@inheritDoc} */ @Override public int hashCode() { int _result = Objects.hash(left, right); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") MutablePairImpl<TLeft,TRight> _other = (MutablePairImpl<TLeft,TRight>) arg0; return (Objects.equals(left, _other.left) && Objects.equals(right, _other.right)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("MutablePairImpl ["); _sb.append("left="); _sb.append(left); _sb.append(", "); _sb.append("right="); _sb.append(right); _sb.append(']'); return _sb.toString(); } }
ImmutablePair.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.*; import com.fortyoneconcepts.valjogen.annotations.types.Mutability; /** * Example that shows how to generate a simple immutable pair class. * Note the tiny difference compared to the mutable pair class example. * * @param <TLeft> First object type in pair. * @param <TRight> Second object type in pair. */ @VALJOGenerate(comment="Example 4") @VALJOConfigure(mutability=Mutability.Immutable) public interface ImmutablePair<TLeft, TRight> { public TLeft getLeft(); public ImmutablePair<TLeft, TRight> setLeft(TLeft left); public TRight getRight(); public ImmutablePair<TLeft, TRight> setRight(TRight right); }
ImmutablePair.java
=> ImmutablePairImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.ImmutablePair<TLeft,TRight>") public final class ImmutablePairImpl<TLeft,TRight> implements ImmutablePair<TLeft,TRight> { private final TLeft left; private final TRight right; public static <TLeft,TRight> ImmutablePairImpl<TLeft,TRight> valueOf(final TLeft left, final TRight right) { ImmutablePairImpl<TLeft,TRight> _instance = new ImmutablePairImpl<TLeft,TRight>(left, right); return _instance; } private ImmutablePairImpl(final TLeft left, final TRight right) { super(); this.left=Objects.requireNonNull(left); this.right=Objects.requireNonNull(right); } /** * {@inheritDoc} */ @Override public TLeft getLeft() { return left; } /** * {@inheritDoc} */ @Override public ImmutablePairImpl<TLeft,TRight> setLeft(final TLeft left) { return new ImmutablePairImpl<TLeft,TRight>(left, this.right); } /** * {@inheritDoc} */ @Override public TRight getRight() { return right; } /** * {@inheritDoc} */ @Override public ImmutablePairImpl<TLeft,TRight> setRight(final TRight right) { return new ImmutablePairImpl<TLeft,TRight>(this.left, right); } /** * {@inheritDoc} */ @Override public int hashCode() { int _result = Objects.hash(left, right); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") ImmutablePairImpl<TLeft,TRight> _other = (ImmutablePairImpl<TLeft,TRight>) arg0; return (Objects.equals(left, _other.left) && Objects.equals(right, _other.right)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("ImmutablePairImpl ["); _sb.append("left="); _sb.append(left); _sb.append(", "); _sb.append("right="); _sb.append(right); _sb.append(']'); return _sb.toString(); } }
SerializablePosition.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows how to specify serialization ID for serialiable classes. */ @VALJOGenerate(comment="Example 5") @VALJOConfigure(serialVersionUID=42) public interface SerializablePosition extends java.io.Serializable { public int getX(); public int getY(); }
SerializablePosition.java
=> SerializablePositionImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.SerializablePosition") public final class SerializablePositionImpl implements SerializablePosition { private static final long serialVersionUID = 42; private final int x; private final int y; public static SerializablePositionImpl valueOf(final int x, final int y) { SerializablePositionImpl _instance = new SerializablePositionImpl(x, y); return _instance; } private SerializablePositionImpl(final int x, final int y) { super(); this.x=x; this.y=y; } /** * {@inheritDoc} */ @Override public int getX() { return x; } /** * {@inheritDoc} */ @Override public int getY() { return y; } /** * {@inheritDoc} */ @Override public int hashCode() { final int _prime = 31; int _result = 1; _result = _prime * _result + Integer.hashCode(x); _result = _prime * _result + Integer.hashCode(y); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") SerializablePositionImpl _other = (SerializablePositionImpl) arg0; return ((x == _other.x) && (y == _other.y)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("SerializablePositionImpl ["); _sb.append("x="); _sb.append(x); _sb.append(", "); _sb.append("y="); _sb.append(y); _sb.append(']'); return _sb.toString(); } }
ExternalizablePosition.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows how to get an auto-implementation of externalizable. */ @VALJOGenerate(comment="Example 6") @VALJOConfigure(serialVersionUID=42) public interface ExternalizablePosition extends java.io.Externalizable { public int getX(); public int getY(); }
ExternalizablePosition.java
=> ExternalizablePositionImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.ExternalizablePosition") public final class ExternalizablePositionImpl implements ExternalizablePosition { private static final long serialVersionUID = 42; private int x; private int y; public static ExternalizablePositionImpl valueOf(final int x, final int y) { ExternalizablePositionImpl _instance = new ExternalizablePositionImpl(x, y); return _instance; } public static ExternalizablePositionImpl valueOf() { ExternalizablePositionImpl _instance = new ExternalizablePositionImpl(); return _instance; } private ExternalizablePositionImpl(final int x, final int y) { super(); this.x=x; this.y=y; } public ExternalizablePositionImpl() { super(); } /** * {@inheritDoc} */ @Override public int getX() { return x; } /** * {@inheritDoc} */ @Override public int getY() { return y; } /** * {@inheritDoc} */ @Override public void writeExternal(final java.io.ObjectOutput arg0) throws java.io.IOException { arg0.writeInt(x); arg0.writeInt(y); } /** * {@inheritDoc} */ @Override public void readExternal(final java.io.ObjectInput arg0) throws java.io.IOException, ClassNotFoundException { x=arg0.readInt(); y=arg0.readInt(); } /** * {@inheritDoc} */ @Override public int hashCode() { final int _prime = 31; int _result = 1; _result = _prime * _result + Integer.hashCode(x); _result = _prime * _result + Integer.hashCode(y); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") ExternalizablePositionImpl _other = (ExternalizablePositionImpl) arg0; return ((x == _other.x) && (y == _other.y)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("ExternalizablePositionImpl ["); _sb.append("x="); _sb.append(x); _sb.append(", "); _sb.append("y="); _sb.append(y); _sb.append(']'); return _sb.toString(); } }
ExtendingByInheritance.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows how use standard subclassing for customization. Generated output will inheriting from the specified base * class (see "BaseClass.java"). In addition the generated abstract class can be futher customized when subclassing it. */ @VALJOGenerate(comment="Example 7") @VALJOConfigure(clazzModifiers= {"ABSTRACT"}, baseClazzName="com.fortyoneconcepts.valjogen.examples.BaseClass") public interface ExtendingByInheritance { public String getGeneratedProperty(); }
See also: BaseClass.java
ExtendingByInheritance.java
, BaseClass.java
) => ExtendingByInheritanceImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.ExtendingByInheritance") abstract class ExtendingByInheritanceImpl extends BaseClass implements ExtendingByInheritance { protected final String generatedProperty; public ExtendingByInheritanceImpl(final int baseValue, final String generatedProperty) { super(baseValue); this.generatedProperty=Objects.requireNonNull(generatedProperty); } /** * {@inheritDoc} */ @Override public String getGeneratedProperty() { return generatedProperty; } /** * {@inheritDoc} */ @Override public int hashCode() { int _result = Objects.hash(generatedProperty); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") ExtendingByInheritanceImpl _other = (ExtendingByInheritanceImpl) arg0; return (Objects.equals(generatedProperty, _other.generatedProperty)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("ExtendingByInheritanceImpl ["); _sb.append("generatedProperty="); _sb.append(generatedProperty); _sb.append(']'); return _sb.toString(); } }
ComparableName.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows how to make generated class implement comparable in a specific way. As we can't refer directly to the generated class directly from our interface * we need to specify the implmentation with it's generic reference as an extra interface that the generated class should implement (in addition to this * main interface). Extra interfaces are resolved only when the implementation is generated. Notice the use of the <code>This</code> macro so we do not have to * hardcode the implementation class name. Notice also how a certain ordering for the compareTo implementation is specified (instead of the default * which is in order of declaration of the properties in the interface). */ @VALJOGenerate(comment="Example 8") @VALJOConfigure(extraInterfaceNames={ "java.lang.Comparable<$(This)>" }, comparableMembers= {"lastName", "firstName" }) public interface ComparableName { public String getFirstName(); public String getLastName(); }
ComparableName.java
=> ComparableNameImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.ComparableName") public final class ComparableNameImpl implements ComparableName, Comparable<ComparableNameImpl> { private final String firstName; private final String lastName; public static ComparableNameImpl valueOf(final String firstName, final String lastName) { ComparableNameImpl _instance = new ComparableNameImpl(firstName, lastName); return _instance; } private ComparableNameImpl(final String firstName, final String lastName) { super(); this.firstName=Objects.requireNonNull(firstName); this.lastName=Objects.requireNonNull(lastName); } /** * {@inheritDoc} */ @Override public String getFirstName() { return firstName; } /** * {@inheritDoc} */ @Override public String getLastName() { return lastName; } /** * {@inheritDoc} */ @Override public int compareTo(final ComparableNameImpl arg0) { int _result; if ((_result=lastName.compareTo(arg0.lastName))!=0) return _result; if ((_result=firstName.compareTo(arg0.firstName))!=0) return _result; return 0; } /** * {@inheritDoc} */ @Override public int hashCode() { int _result = Objects.hash(firstName, lastName); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") ComparableNameImpl _other = (ComparableNameImpl) arg0; return (Objects.equals(firstName, _other.firstName) && Objects.equals(lastName, _other.lastName)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("ComparableNameImpl ["); _sb.append("firstName="); _sb.append(firstName); _sb.append(", "); _sb.append("lastName="); _sb.append(lastName); _sb.append(']'); return _sb.toString(); } }
package-info.java
/** * Example of how to configure ValjoGen defaults for interfaces in a package. * * Note how a @VALJOConfigure annotation can be applied here as a default for all examples. The annotation * will be overridden it its entirety if also applied on an interface of an example. * * @author mmc */ @VALJOConfigure(headerFileName="Header.txt", comment="Example 9") package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure;
See also: Header.txt
JsonWithJackson.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.*; import com.fortyoneconcepts.valjogen.annotations.types.DataConversion; /** * Example that shows how to generate a mutable or immutable class with Jackson annotations, so it can be easily converted to/from JSON. * If using JDK8, consider using {@link DataConversion#JACKSON_DATABIND_ANNOTATIONS_WITH_JDK8_PARAMETER_NAMES} instead. * * @see <a href="https://github.com/FasterXML/jackson-annotations">jackson-annotations</a> */ @VALJOGenerate(comment="Example 10") @VALJOConfigure(dataConversion=DataConversion.JACKSON_DATABIND_ANNOTATIONS) public interface JsonWithJackson { public String getName(); public int getAge(); }
JsonWithJackson.java
=> JsonWithJacksonImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.JsonWithJackson") public final class JsonWithJacksonImpl implements JsonWithJackson { private final String name; private final int age; @JsonCreator public static JsonWithJacksonImpl valueOf(@JsonProperty("name") final String name, @JsonProperty("age") final int age) { JsonWithJacksonImpl _instance = new JsonWithJacksonImpl(name, age); return _instance; } private JsonWithJacksonImpl(final String name, final int age) { super(); this.name=Objects.requireNonNull(name); this.age=age; } /** * {@inheritDoc} */ @Override public String getName() { return name; } /** * {@inheritDoc} */ @Override public int getAge() { return age; } /** * {@inheritDoc} */ @Override public int hashCode() { final int _prime = 31; int _result = 1; _result = _prime * _result + Objects.hashCode(name); _result = _prime * _result + Integer.hashCode(age); return _result; } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") JsonWithJacksonImpl _other = (JsonWithJacksonImpl) arg0; return (Objects.equals(name, _other.name) && (age == _other.age)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("JsonWithJacksonImpl ["); _sb.append("name="); _sb.append(name); _sb.append(", "); _sb.append("age="); _sb.append(age); _sb.append(']'); return _sb.toString(); } }
CustomHashCode.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows how to apply a custom template to change the generated code for known methods. In this case to support caching of hashCode. */ @VALJOGenerate(comment="Example 12") @VALJOConfigure(customJavaTemplateFileName="custom_hashCode.stg") public interface CustomHashCode { public String getFirstName(); public String getLastName(); }
See also: custom_hashCode.stg
CustomHashCode.java
, custom_hashCode.stg
) => CustomHashCodeImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.CustomHashCode") public final class CustomHashCodeImpl implements CustomHashCode { private volatile transient int cachedHashCode = 0; private final String firstName; private final String lastName; public static CustomHashCodeImpl valueOf(final String firstName, final String lastName) { CustomHashCodeImpl _instance = new CustomHashCodeImpl(firstName, lastName); return _instance; } private CustomHashCodeImpl(final String firstName, final String lastName) { super(); this.firstName=Objects.requireNonNull(firstName); this.lastName=Objects.requireNonNull(lastName); } /** * {@inheritDoc} */ @Override public String getFirstName() { return firstName; } /** * {@inheritDoc} */ @Override public String getLastName() { return lastName; } /** * Returns a hash code value for the object or cached value if already called. */ @Override public int hashCode() { if (cachedHashCode!=0) return cachedHashCode; int _result = Objects.hash(firstName, lastName); return (cachedHashCode=_result); } /** * {@inheritDoc} */ @Override public boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") CustomHashCodeImpl _other = (CustomHashCodeImpl) arg0; return (Objects.equals(firstName, _other.firstName) && Objects.equals(lastName, _other.lastName)); } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("CustomHashCodeImpl ["); _sb.append("firstName="); _sb.append(firstName); _sb.append(", "); _sb.append("lastName="); _sb.append(lastName); _sb.append(']'); return _sb.toString(); } }
CustomLogginngWithRegions.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows how to apply a simple custom template to provide constructor logging by overriding existing regions. */ @VALJOGenerate(comment="Example 20") @VALJOConfigure(customJavaTemplateFileName="custom_logging.stg", synchronizedAccessEnabled=true) public interface CustomLogginngWithRegions { public String getName(); public void setName(String name); }
See also: custom_logging.stg
CustomLogginngWithRegions.java
, custom_logging.stg
) => CustomLogginngWithRegionsImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; import java.util.logging.Logger; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.CustomLogginngWithRegions") public final class CustomLogginngWithRegionsImpl implements CustomLogginngWithRegions { private final static Logger LOGGER = Logger.getLogger(CustomLogginngWithRegionsImpl.class.getName()); private String name; public static CustomLogginngWithRegionsImpl valueOf(final String name) { CustomLogginngWithRegionsImpl _instance = new CustomLogginngWithRegionsImpl(name); return _instance; } public static CustomLogginngWithRegionsImpl valueOf() { CustomLogginngWithRegionsImpl _instance = new CustomLogginngWithRegionsImpl(); return _instance; } private CustomLogginngWithRegionsImpl(final String name) { super(); LOGGER.fine(() -> "Constructing CustomLogginngWithRegionsImpl"); this.name=Objects.requireNonNull(name); } private CustomLogginngWithRegionsImpl() { super(); LOGGER.fine(() -> "Constructing CustomLogginngWithRegionsImpl"); } /** * {@inheritDoc} */ @Override public synchronized String getName() { return name; } /** * {@inheritDoc} */ @Override public synchronized void setName(final String name) { this.name=Objects.requireNonNull(name); } /** * {@inheritDoc} */ @Override public synchronized int hashCode() { int _result = Objects.hash(name); return _result; } /** * {@inheritDoc} */ @Override public synchronized boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") CustomLogginngWithRegionsImpl _other = (CustomLogginngWithRegionsImpl) arg0; return (Objects.equals(name, _other.name)); } /** * {@inheritDoc} */ @Override public synchronized String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("CustomLogginngWithRegionsImpl ["); _sb.append("name="); _sb.append(name); _sb.append(']'); return _sb.toString(); } }
SimpleCustomMethod.java
package com.fortyoneconcepts.valjogen.examples; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows how to apply a basic custom template implementing a simple custom method. A custom method that can tell when a property was last changed. * Example also shows how to make the generated mutable class thread safe. */ @VALJOGenerate(comment="Example 21") @VALJOConfigure(customJavaTemplateFileName="simple_custom_method.stg", synchronizedAccessEnabled=true) public interface SimpleCustomMethod { public String getName(); public void setName(String name); // Custom method here: public long nanoLastUpdated(); }
See also: simple_custom_method.stg
SimpleCustomMethod.java
, simple_custom_method.stg
) => SimpleCustomMethodImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.SimpleCustomMethod") public final class SimpleCustomMethodImpl implements SimpleCustomMethod { private long changeNanoTime; private String name; public static SimpleCustomMethodImpl valueOf(final String name) { SimpleCustomMethodImpl _instance = new SimpleCustomMethodImpl(name); return _instance; } public static SimpleCustomMethodImpl valueOf() { SimpleCustomMethodImpl _instance = new SimpleCustomMethodImpl(); return _instance; } private SimpleCustomMethodImpl(final String name) { super(); this.name=Objects.requireNonNull(name); changeNanoTime=System.nanoTime(); } private SimpleCustomMethodImpl() { super(); changeNanoTime=System.nanoTime(); } /** * {@inheritDoc} */ @Override public synchronized String getName() { return name; } /** * {@inheritDoc} */ @Override public synchronized void setName(final String name) { changeNanoTime=System.nanoTime(); this.name=Objects.requireNonNull(name); } /** * Returnes the last time this class was updated. */ @Override public synchronized long nanoLastUpdated() { return changeNanoTime; } /** * {@inheritDoc} */ @Override public synchronized int hashCode() { int _result = Objects.hash(name); return _result; } /** * {@inheritDoc} */ @Override public synchronized boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") SimpleCustomMethodImpl _other = (SimpleCustomMethodImpl) arg0; return (Objects.equals(name, _other.name)); } /** * {@inheritDoc} */ @Override public synchronized String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("SimpleCustomMethodImpl ["); _sb.append("name="); _sb.append(name); _sb.append(']'); return _sb.toString(); } }
AdvancedCustomDigestMethod.java
package com.fortyoneconcepts.valjogen.examples; import java.util.List; import com.fortyoneconcepts.valjogen.annotations.VALJOConfigure; import com.fortyoneconcepts.valjogen.annotations.VALJOGenerate; /** * Example that shows a non-trivial custom template implementing an advanced custom method that calculate a digest of object state. * The generated class is set to inherit from a base class that provide both contract and helper methods. * The example also shows how to make the generated mutable class thread safe. */ @VALJOGenerate(comment="Example 23") @VALJOConfigure(customJavaTemplateFileName="advanced_custom_method.stg", baseClazzName="DigestBaseClass", synchronizedAccessEnabled=true) public interface AdvancedCustomDigestMethod { public String getName(); public void setName(String name); public int getAge(); public void setAge(int age); public String[] getAddress(); public void setAddress(String[] address); public List<String> getAltAddress(); public void setAltAddress(List<String> altAddress); public boolean isVerified(); public void setVerified(boolean verified); // Custom method calculateDigest declared in base class. }
See also: DigestBaseClass.java
, advanced_custom_method.stg
AdvancedCustomDigestMethod.java
, DigestBaseClass.java
, advanced_custom_method.stg
) => AdvancedCustomDigestMethodImpl.java
:/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */ package com.fortyoneconcepts.valjogen.examples; import java.util.Arrays; import java.util.Objects; import javax.annotation.Generated; import java.security.MessageDigest; @Generated(value = "com.fortyoneconcepts.valjogen", date="2014-11-22T10:46Z", comments="Generated by ValjoGen code generator (ValjoGen.41concepts.com) from com.fortyoneconcepts.valjogen.examples.AdvancedCustomDigestMethod") public final class AdvancedCustomDigestMethodImpl extends DigestBaseClass implements AdvancedCustomDigestMethod { private String name; private int age; private String[] address; private java.util.List<String> altAddress; private boolean verified; public static AdvancedCustomDigestMethodImpl valueOf(final String name, final int age, final String[] address, final java.util.List<String> altAddress, final boolean verified) { AdvancedCustomDigestMethodImpl _instance = new AdvancedCustomDigestMethodImpl(name, age, address, altAddress, verified); return _instance; } public static AdvancedCustomDigestMethodImpl valueOf() { AdvancedCustomDigestMethodImpl _instance = new AdvancedCustomDigestMethodImpl(); return _instance; } private AdvancedCustomDigestMethodImpl(final String name, final int age, final String[] address, final java.util.List<String> altAddress, final boolean verified) { super(); this.name=Objects.requireNonNull(name); this.age=age; this.address=Objects.requireNonNull(address); this.altAddress=Objects.requireNonNull(altAddress); this.verified=verified; } private AdvancedCustomDigestMethodImpl() { super(); } /** * {@inheritDoc} */ @Override public synchronized String getName() { return name; } /** * {@inheritDoc} */ @Override public synchronized void setName(final String name) { this.name=Objects.requireNonNull(name); } /** * {@inheritDoc} */ @Override public synchronized int getAge() { return age; } /** * {@inheritDoc} */ @Override public synchronized void setAge(final int age) { this.age=age; } /** * {@inheritDoc} */ @Override public synchronized String[] getAddress() { return address; } /** * {@inheritDoc} */ @Override public synchronized void setAddress(final String[] address) { this.address=Objects.requireNonNull(address); } /** * {@inheritDoc} */ @Override public synchronized java.util.List<String> getAltAddress() { return altAddress; } /** * {@inheritDoc} */ @Override public synchronized void setAltAddress(final java.util.List<String> altAddress) { this.altAddress=Objects.requireNonNull(altAddress); } /** * {@inheritDoc} */ @Override public synchronized boolean isVerified() { return verified; } /** * {@inheritDoc} */ @Override public synchronized void setVerified(final boolean verified) { this.verified=verified; } /** * Returnes the message digest of the members in the class. */ @Override public synchronized byte[] calculateDigest(final String algorithm) throws java.security.NoSuchAlgorithmException { MessageDigest digester = MessageDigest.getInstance(algorithm); digester.update(getBytes(name)); digester.update(getBytes(age)); for (int i=0; i<address.length; ++i) digester.update(getBytes(address[i])); for (String i : altAddress) digester.update(getBytes(i)); digester.update(getBytes(verified)); return digester.digest(); } /** * {@inheritDoc} */ @Override public synchronized int hashCode() { final int _prime = 31; int _result = 1; _result = _prime * _result + Objects.hashCode(name); _result = _prime * _result + Integer.hashCode(age); _result = _prime * _result + Arrays.hashCode(address); _result = _prime * _result + Objects.hashCode(altAddress); _result = _prime * _result + Boolean.hashCode(verified); return _result; } /** * {@inheritDoc} */ @Override public synchronized boolean equals(final Object arg0) { if (this == arg0) return true; if (arg0 == null) return false; if (getClass() != arg0.getClass()) return false; @SuppressWarnings("unchecked") AdvancedCustomDigestMethodImpl _other = (AdvancedCustomDigestMethodImpl) arg0; return (Objects.equals(name, _other.name) && (age == _other.age) && Arrays.equals(address, _other.address) && Objects.equals(altAddress, _other.altAddress) && (verified == _other.verified)); } /** * {@inheritDoc} */ @Override public synchronized String toString() { final StringBuilder _sb = new StringBuilder(); _sb.append("AdvancedCustomDigestMethodImpl ["); _sb.append("name="); _sb.append(name); _sb.append(", "); _sb.append("age="); _sb.append(age); _sb.append(", "); _sb.append("address="); _sb.append(Arrays.toString(address)); _sb.append(", "); _sb.append("altAddress="); _sb.append(altAddress); _sb.append(", "); _sb.append("verified="); _sb.append(verified); _sb.append(']'); return _sb.toString(); } }
BaseClass.java
package com.fortyoneconcepts.valjogen.examples; /** * Example of a preexisting base class that generated code can extend from. * Used by the "ExtendingByInheritance.java" example. * * Note that constructors of the generated class will delegate to available * constructors in the base class. Also keep it mind that if you need * serialization base classes must be serializable for any generated * subclasses like ours (without a default constructor) to be serializable. */ public class BaseClass { protected final int baseValue; public BaseClass(int baseValue) { this.baseValue=baseValue; } }
See also: ExtendingByInheritance.java
DigestBaseClass.java
package com.fortyoneconcepts.valjogen.examples; /** * Example of a preexisting abstract base class that a generated class can extend from. * * In this case the bease class both specifies an abstract method that the * generated class must implement (using custom templates) as well as * helper methods useful for calculating digests. Helper methods using overloading * like here can makes custom templates much simpler to write. * * Used by the "AdvancedCustomDigestMethod.java" example and its assoicated template "advanced_custom_method.stg". * * Note that the current set of getBytes methods only handle a subset of types such as bytes, integers * and strings (arrays and collections of thoses are handled by the custom template). For a real implementation, * one should overload with additional getBytes methods. */ public abstract class DigestBaseClass { // Will be implemented by a custom template specified in the interface for the example. public abstract byte[] calculateDigest(String algorithm) throws java.security.NoSuchAlgorithmException; protected static final byte getBytes(boolean v) { return v ? (byte)1 : (byte)0; } protected static final byte[] getBytes(int v) { return new byte[] { (byte)((v >> 24) & 0xff), (byte)((v >> 16) & 0xff), (byte)((v >> 8) & 0xff), (byte)((v >> 0) & 0xff), }; } protected static final byte[] getBytes(String v) { return v.getBytes(); } }
See also: AdvancedCustomDigestMethod.java
, advanced_custom_method.stg
advanced_custom_method.stg
/**
* This custom template shows how to implement a non-trivial custom method declared in the interface that iterate through all members of the class.
*
* The custom template for the new custom method must have a specific name of "method_"+specifier and the template must be configured by
* the VALJOConfigure annotation. See javadoc on VALJOConfigure#customJavaTemplateFileName for details about this. Also refer to
* javadocs in the com.fortyoneconcepts.valjogen.model packakge for template arguments clazz of type Clazz and method of type Method.
*
* The digest implementation iterates though all class members (fields) and calls update methods on a digester before returning the digest. Note,
* how the abstract base class in this example supplies helper methods to get byte arrays from member values.
*/
@class.imports() ::= <<
<! Add our log class manually - could also have been done easier with VALJOConfigure's importClasses option !>
<@super.imports()>
import java.security.MessageDigest;
>>
method_calculateDigest_String(clazz, method) ::= <<
/**
* Returnes the message digest of the members in the class.
*/
<method.annotations:annotationLine()><\\>
<declare_method(clazz, method)>
{
<! Construct a digest using first algorithm specified in first argument of method (we could hardcode this but in the example we use the model to tell us the name of the argument) !>
MessageDigest digester = MessageDigest.getInstance(<first(method.parameters).name>);
<! Iterate through all members of the class and call one of the template methods below depending on the overall type of the member !>
<clazz.members:{m | <(toByteTemplateNamesByTypeCategory.(m.type.typeCategory))(m.name, m.type)> }; wrap, anchor, separator="\n">
return digester.digest();
}
>>
/* A static ST map that works as a switch so types can be handled by different templates depending on category */
toByteTemplateNamesByTypeCategory ::= [ "PRIMITIVE": "toByte_primitive", "ARRAY": "toByte_array", default: "toByte_object"]
/* Primitive members are handled here. Note how bytes are easier dealth with then other primitives */
toByte_primitive(var, type) ::= <%
<if(type.primitiveByte)>
digester.update(<var>);
<else>
digester.update(getBytes(<var>));
<endif>
%>
/* Arrays are handled here. Note how primitive arrays of bytes are easier dealth with then other arrays */
toByte_array(var, type) ::= <<
<if(type.arrayComponentType.primitiveByte)>
digester.update(<var>);<\\>
<else><\\>
for (int i=0; i\<<var>.length; ++i)
digester.update(getBytes(<var>[i]));<\\>
<endif>
>>
/* Handle iterables but refer all other types to our base class in this implementation. */
toByte_object(var, type) ::= <<
<if(type.ofType_Iterable)><\\>
for (<first(type.genericTypeArguments).name> i : <var>)
digester.update(getBytes(i));<\\>
<else><\\>
digester.update(getBytes(<var>));
<endif>
>>
See also: AdvancedCustomDigestMethod.java
, DigestBaseClass.java
custom_hashCode.stg
/**
* This custom template shows how to add caching to the generated hashCode method. It overrides StringTemplate regions to
* add a new instance member to hold the cached value, add a check in start of the hashCode method and store
* the returned value of hashCode to the assoicated instance member. Finally it adds a javadoc comment on top
* of the hashCode method. Refer to the *.stg files in the source for how to find the refered regions.
*
* Note that regions must be qualified with the name of the template they are declared in and how <@super.returnvalue()>
* can be used to refer to the region's orginal content.
*/
@class.before_instance_members() ::= <<
private volatile transient int cachedHashCode = 0;
>>
@method_hashCode.preamble() ::= <<
if (cachedHashCode!=0)
return cachedHashCode;
>>
@method_hashCode.returnvalue() ::= <%
<! Captures return value before return statement. Could also have overriden method_hashCode.postamble instead !>
(cachedHashCode=<@super.returnvalue()>)
%>
@method_hashCode.javadoc() ::= <<
/**
* Returns a hash code value for the object or cached value if already called.
*/
>>
See also: CustomHashCode.java
custom_logging.stg
/**
* This custom template shows how to add logging of created instances to a generated class. It overrides StringTemplate regions to
* add an import, add a static logger instance and add a log message at the end of the constructor. Refer to the *.stg files
* in the source for how to find the refered regions.
*
* Note that regions must be qualified with the name of the template they are declared in, that they can refer to the
* stringtemplate arguments of the template they are called from and how <@super.imports()> are used to refer to the
* region's orginal content.
*
* NOTE 1: The import could also have been done easier with VALJOConfigure's importClasses option - this is just an alternative.
*/
@class.imports() ::= <<
<! Add our log class manually - Note 1 !>
<@super.imports()>
import java.util.logging.Logger;
>>
@class.before_class_members() ::= <<
private final static Logger LOGGER = Logger.getLogger(<clazz.name>.class.getName());
>>
@method_this.preamble() ::= <<
LOGGER.fine(() -> "Constructing <clazz.name>");
>>
See also: CustomLogginngWithRegions.java
simple_custom_method.stg
/**
* This custom template shows how to implement a custom method declared in the interface. First it overrides StringTemplate regions to
* add a variable holding a time then it modifies the constructor and setter to update the time of change. Finally, a new method
* is added to return the time as declared in the interface.
*
* The custom template for the method must have a specific name of "method_"+specifier and the template must be configured by
* the VALJOConfigure annotation. See javadoc on VALJOConfigure#customJavaTemplateFileName for details about this. Also refer to
* javadocs in the com.fortyoneconcepts.valjogen.model packakge for template arguments clazz of type Clazz and method of type Method.
*
* Refer to the *.stg files in the source for how to find the refered regions and for descriptions of the used sub-template
* declare_method that can help with generating the correct declaration.
*
*/
@class.before_instance_members() ::= <<
private long changeNanoTime;
>>
@mutable_setter.preamble() ::= <%
changeNanoTime=System.nanoTime();
%>
@method_this.postamble() ::= <%
changeNanoTime=System.nanoTime();
%>
method_nanoLastUpdated(clazz, method) ::= <<
/**
* Returnes the last time this class was updated.
*/
<method.annotations:annotationLine()><\\>
<declare_method(clazz, method)>
{
return changeNanoTime;
}
>>
See also: SimpleCustomMethod.java
Header.txt
/* This is a sample header for VALJOGen examples provided by the file "Header.txt" and configured by "package-info.java" */
See also: package-info.java