jqwik strategies for combining arbitraries - java

(Context: my background in property-based testing is mostly from scala's scalacheck library, the use of some of the types and annotations in jqwik feels a bit different and there are a couple paradigms I can't quite get the hang of yet.)
I'm not sure how best to combine existing Arbitrary definitions for primitive types to produce a re-usable (needed for more than a single #Property or test class) Arbitrary that is built atop other Aribtrary definitions I've defined.
Given this is probably much clearer with an illustration:
// assume this has a builder pattern or all-args constructor.
// consider this is some sort of core domain object that I need in various
// test suites
public class MyComplexClass {
private final String id; // positive-integer shaped
private final String recordId; // uuid-shaped
private final String creatorId; // positive-integer shaped
private final String editorId; // positive-integer shaped
private final String nonce; // uuid-shaped
private final String payload; // random string
}
My instinct is to define Aribrary<String> that produces UUID-like strings and another that produces positive integer strings, something like:
public class MyArbitraries {
public Arbitrary<String> arbUuidString() {
return Combinators.combine(
Arbitraries.longs(), Arbitraries.longs(), Arbitraries.of(Set.of('8', '9', 'a', 'b')))
.as((l1, l2, y) -> {
StringBuilder b = new StringBuilder(new UUID(l1, l2).toString());
b.setCharAt(14, '4');
b.setCharAt(19, y);
return UUID.fromString(b.toString());
});
}
public Arbitrary<String> arbNumericIdString() {
return Arbitraries.shorts().map(Math::abs).map(i -> "" + i);
}
}
But then I'm not sure the best way to utilize these to produce an Arbitrary< MyComplexClass>. I'd want something like:
public class MyDomain extends DomainContextBase {
#Provider
public Arbitrary<MyComplexClass> arbMyComplexClass() {
return Builders.withBuilder(MyComplexClass::newBuilder)
// best way to reference these?!
.use(arbNumericIdString()).in(MyComplexClass.Builder::setId)
.use(arbUuidString()).in(MyComplexClass.Builder::setCreatorId)
// etc.
.build(MyComplexClass.Builder::build);
}
}
My understanding here is:
I cannot use #ForAll to 'inject' or provide these Arbitraries as ForAll is only supported in #Property-annotated methods
I cannot use #Domain here for similar reasons
I can't really use ArbitrarySupplier or similar as there is no obvious 'type' here, it's mostly just a bunch of strings
Is the best option to just create static Arbitrary<String> functions and call them directly?

One initial comment: #ForAll also works in methods annotated with #Provide and in domains. Here's a simple example:
class MyDomain extends DomainContextBase {
#Provide
public Arbitrary<String> strings(#ForAll("lengths") int length) {
return Arbitraries.strings().alpha().ofLength(length);
}
#Provide
public Arbitrary<Integer> lengths() {
return Arbitraries.integers().between(3, 10);
}
// Will not be used by strings() method
#Provide
public Arbitrary<Integer> negatives() {
return Arbitraries.integers().between(-100, -10);
}
}
class MyProperties {
#Property(tries = 101)
#Domain(MyDomain.class)
public void printOutAlphaStringsWithLength3to10(#ForAll String stringsFromDomain) {
System.out.println(stringsFromDomain);
}
}
Maybe the confusing thing is that the string reference in #ForAll("myString") is only evaluated locally (the class itself, superclasses and containing classes).
This is by purpose, in order to prevent string-based reference magic;
having to fall back to strings in the first place - since method refs cannot be used in Java annotations - is already bad enough.
As for your concrete question:
Is the best option to just create static Arbitrary functions and call them directly?
I consider that a "good enough" approach for sharing generators within a single domain or when you have several related domains that inherit from a common superclass.
When you want to share generators across unrelated domains, you'll have to either:
Use type-based resolution: Introduce value types for things like RecordId, UUIDString etc. Then you can use domains (or registered ArbitraryProviders to generate based on type.
Introduce annotations to mark different variants of the same type.
You can then check the annotation in your provider method or arbitrary provider. Here's an example:
class MyNumbers extends DomainContextBase {
#Provide
Arbitrary<Integer> numbers() {
return Arbitraries.integers().between(0, 255);
}
}
#Domain(MyNumbers.class)
class MyDomain extends DomainContextBase {
#Target({ElementType.PARAMETER})
#Retention(RetentionPolicy.RUNTIME)
#interface Name {}
#Target({ElementType.PARAMETER})
#Retention(RetentionPolicy.RUNTIME)
#interface HexNumber {}
#Provide
public Arbitrary<String> names(TypeUsage targetType) {
if (targetType.isAnnotated(Name.class)) {
return Arbitraries.strings().alpha().ofLength(5);
}
return null;
}
#Provide
public Arbitrary<String> numbers(TypeUsage targetType) {
if (targetType.isAnnotated(HexNumber.class)) {
return Arbitraries.defaultFor(Integer.class).map(Integer::toHexString);
}
return null;
}
}
#Property(tries = 101)
#Domain(MyDomain.class)
public void generateNamesAndHexNumbers(
#ForAll #MyDomain.Name String aName,
#ForAll #MyDomain.HexNumber String aHexNumber
) {
System.out.println(aName);
System.out.println(aHexNumber);
}
This examples also shows how one domain (MyNumbers) can be used
in another domain (MyDomain) through annotating the domain implementation class and either having a parameter being injected or use
Arbitraries.defaultFor(TypeProvidedInOtherDomain.class).
But maybe there's a useful feature for sharing arbitraries missing in jqwik.
The jqwik team's happy about any suggestion.

Related

What is the recommended pattern for 2 classes that are identical apart from constant names?

I have an interface and 2 classes implementing the interface. The only difference between the classes is the constant name, they are being used for the same thing but from different locations. I just want to count how many times the method is called from each different location. Is there a better way of doing this without the repetition or passing in the metric name as a string?
public interface OldIdResolver {
Optional<String> getNewIdFromOldId();
}
public class CustomFieldIdResolver implements OldIdResolver {
Optional<String> getIdFromLegacyId(String oldId) {
Optional<Id> newIdOptional = idService.getNewIdFromOldId(oldId);
if (newIdOptional.isPresent()) {
statsDClient.incrementCounter("customField.oldIdUsed");
}
return newIdOptional;
}
}
public class SearcherIdResolver implements OldIdResolver {
Optional<String> getIdFromLegacyId(String oldId) {
Optional<Id> newIdOptional = idService.getNewIdFromOldId(oldId);
if (newIdOptional.isPresent()) {
statsDClient.incrementCounter("searcher.oldIdUsed");
}
return newIdOptional;
}
}
Ordinarily you'd simply make one class and make a constructor:
public class AnyMetricIdResolver implements OldResolver {
private final String metricName;
public AnyMetricIdResolver(String metricName) {
this.metricName = metricName;
}
Optional<String> getIdFromLegacyId(String oldId) {
Optional<Id> newIdOptional = idService.getNewIdFromOldId(oldId);
if (newIdOptional.isPresent()) {
statsDClient.incrementCounter(metricName);
}
return newIdOptional;
}
}
If for some reason that's not good enough (you were rather vague with 'passing the metric name as a string'), you can make an actual class for each kind of metric string, but still do some code reuse. Keep the IdResolver from above (you may want to make it package private if you must), then start subclassing that:
public class SearcherIdResolver extends AnyMetricIdResolver {
public SearcherIdResolver() {
super("searcher.oldIdUsed");
}
}
You can't make a bunch of classes without actually writing them all, unless you use code generation tools such as Annotation Processors which is certainly possible, but I doubt that's what you're looking for here.

Making a code using enum generic

I have a code which was initially designed for just a single team where they were passing an enum [which stores list of tasks] to an api. This api then progates the use of this enum to many other classes.
Now i have a task where this code needs to be used by multiple teams and they can pass there own set of tasks in form of enums.
Given the current implementation i dont think it is feasible to support multiple teams which completely overhauling the code because enum's cannot extend other enums.
Is there any way to implement this without massive changes?
But... enums can implement interfaces, for example:
public interface Task {
int getPriority(); // just for example
// plus whatever methods define a task
}
public enum Team1Task implements Task {
Task1(1),
Task2(3);
private final int priority;
private Team1Task(int priority) {
this.priority = priority;
}
public int getPriority() {
return priority;
}
}
Now we can employ java generic kung fu to specify a generic parameter bounded to a suitable enum:
public class TaskProcessor<T extends Enum<T> & Task> {
public void process(T task) {
// do something with task
}
}
To use it:
TaskProcessor<Team1Task> p = new TaskProcessor<Team1Task>();
p.process(Team1Task.Open); // will only accept a Team1Task instance
FYI, as a curiosity of generics, you can alternatively use this bound to achieve the same thing:
public class TaskProcessor<T extends Enum<? extends Task>> {
Although I can find no practical difference in effect, I find it lacks the clarity and familiar pattern of the intersection bound above. For more on this see this question.
It is comparatively easy to make much of the work around enums generic.
Here's a severely cut-down example. It defines a generic database Table class that takes an enum Column as its defining type. The enum defines what columns are in the table. The defining type is an enum that also implements an interface which is a really useful trick.
public class Table<Column extends Enum<Column> & Table.Columns> {
// Name of the table.
protected final String tableName;
// All of the columns in the table. This is actually an EnumSet so very efficient.
protected final Set<Column> columns;
/**
* The base interface for all Column enums.
*/
public interface Columns {
// What type does it have in the database?
public Type getType();
}
// Small list of database types.
public enum Type {
String, Number, Date;
}
public Table(String tableName,
Set<Column> columns) {
this.tableName = tableName;
this.columns = columns;
}
}
You can now create your real table with something like:
public class VersionTable extends Table<VersionTable.Column> {
public enum Column implements Table.Columns {
Version(Table.Type.String),
ReleaseDate(Table.Type.Date);
final Table.Type type;
Column(Table.Type type) {
this.type = type;
}
#Override
public Type getType() {
return type;
}
}
public VersionTable() {
super("Versions", EnumSet.allOf(Column.class));
}
}
Note that this is a truly trivial example but with a little work it is easy to move a lot of your enum work into the parent class.
This technique does retain the type-safety checks you get when using generics.
Enums can implement interfaces. I would recommend coming up with a reasonable interface for the task. make your enum implement the interface and your code will continue to work just fine. other teams can use whatever interface implementation they desire (their own enum or something else). (note, without code it's hard to make very explicit recommendations).
You probably should not use enums for this, but if you want, you can implement logic in helper class, or set of classes that extend each other, and make enums a thin wrappers saround it:
public enum MyTaskEnum {
A, B, C;
private final TaskEnumHelper helper = new TaskEnumHelper();
public void foo (int x, int y)
{
helper.foo (x, y);
}
}

Extending enums

I have a number of enums that each have the same fields and the same methods.
public enum AddressSubType {
DOM("dom"), INTL("intl"), POSTAL("postal");
private final String keyword;
private AddressSubType(String keyword) {
this.keyword = keyword;
}
public String getKeyword() {
return keyword;
}
#Override
public String toString() {
return keyword;
}
}
public enum EmailSubType {
INTERNET("internet"), X400("x.400");
private final String keyword;
private EmailSubType(String keyword) {
this.keyword = keyword;
}
public String getKeyword() {
return keyword;
}
#Override
public String toString() {
return keyword;
}
}
Is there a way for these enums to share the fields and methods (like a parent class)? I know that it's not possible to extend enums. Thanks.
You could create a Value class
public class Value {
private final String keyword;
private Value(String keyword) {
this.keyword = keyword;
}
public String getKeyword() {
return keyword;
}
#Override
public String toString() {
return keyword;
}
}
Then you can create Classes with public static final values like this :
public class AddressSubType extend Value {
public static final AddressSubType DOM = new AddressSubType("DOM");
public static final AddressSubType INTL = new AddressSubType("intl");
...
private AddressSubType(String keyword) {
super(keyword);
}
}
I would probably combine them into a single enum object where some are initialized with an "Postal" flag set to true and some have the "email" flag set to true since the two are really just different "types" of addresses.
You can then have it return iterators for either if you wish to access them separately or you can iterate over the whole thing.
You may also find some of the rest of your code becoming simplified, for instance just having a collection of "Address"es and checking at runtime to see if a given address is email or postal.
But it depends on how similar they really are.
You can declare an interface that they both can implement. This would allow you to pass either enum type as an argument to a method that only cares about specific methods on that inerface. However, this will only allow you to "share" the method signatures, not the fields or the method implementations.
If your enums are as trivial as in the given example, you don't have any significant amount of code repetition, so this probably isn't a problem. If you find that your methods have more complex, repetitive code, you should consider delegating that responsibility to a separate class.
If you really want to model an inheritance pattern (e.g. EmailAddress "is a" Address), then you'll need to get away from enums. You could just use some static fields to simulate the enum pattern, but have each of them be an instance of a specific class.
I will be the one to say it. This is an awful idea.
You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile timeā€”for example, the choices on a menu, command line flags, and so on. source
The enum does not care about anything else except the hard coded values inside. Typically when one decides to group things in an Object Oriented way, they make sure that all of the objects are related. By virtue of being an enum these files are no more related than two classes that are subtypes of Object. If you are looking to have shared functionality between all enums in your domain you will want to look at some static functions, or a utility class as it is often referred to (this has its own series of issues at the end of the day). Essentially the class will have a series of functions that encapsulate all the shared logic, the signature will generally look like so:
function foo(Enum enumeration)
There's not much you can do in this case, and even in a more complex example, the best place to put common code might be in a utility class that all the enums could use, or in a separate class that would be included in the enums via composition (each enum would have an instance of that class, perhaps called Keyword).
If the code for the toString method were complex and you didn't want to restate it in each enum, or move it to a contained object, Java 8 has a mechanism that you could use. It is overkill in this example. You could define an interface that your enums would all use. The state (keyword) must still live in your enums, since interfaces cannot have state, but starting with Java 8 you can provide default implementations of methods:
public interface Common {
String getKeyword();
String toString() default {
return getKeyword();
}
String toDescriptiveString() default {
char firstLetter = getKeyword().charAt(0);
boolean vowel =
firstLetter == 'a' || firstLetter == 'e' ||
firstLetter == 'i' || firstLetter == 'o' ||
firstLetter == 'u' || firstLetter == 'x';
// the letter x is pronounced with an initial vowel sound (eks)
return (vowel?"an ":"a ") + getKeyword() + " address";
}
}
Your enums would implement this interface:
public enum AddressSubType implements Common {
DOM("dom"), INTL("intl"), POSTAL("postal");
private final String keyword;
private AddressSubType(String keyword) {
this.keyword = keyword;
}
#Override
public String getKeyword() {
return keyword;
}
#Override
public String toString() {
return Common.super.toString();
}
}
public enum EmailSubType implements Common {
INTERNET("internet"), X400("x.400");
private final String keyword;
private EmailSubType(String keyword) {
this.keyword = keyword;
}
#Override
public String getKeyword() {
return keyword;
}
#Override
public String toString() {
return Common.super.toString();
}
}
Notice the strange new syntax in the toString methods. The rule for default methods in interfaces is that method resolution always prefers class methods over interfaces. So even though we provide a default implementation of toString in Common, the one in the enum will take precedence, and the one in Object would if there wasn't one in the enum. So if you want to use a default method from an interface that supersedes one of the methods from Object (like toString, or hashCode, or equals), then you have to call it explicitly with this new interface.super.method() syntax.
We don't have to jump through any extra hoops for the toDescriptiveString method, though. That one is brand new in interface Common, and it isn't provided by our enums, so they get the default implementation provided by the interface. (If they wanted to override it with their own method, they could, just like any other inherited method.)
We can use the default methods like any other methods of an object, of course:
public class Test {
public static void main(String[] args) {
for (AddressSubType a : AddressSubType.values()) {
System.out.println(a.toDescriptiveString());
}
for (EmailSubType e : EmailSubType.values()) {
System.out.println(e.toDescriptiveString());
}
}
}
Which prints out:
a dom address
an intl address
a postal address
an internet address
an x.400 address
In this case, however, if it wasn't for the rather verbose toDescriptiveString method, the enum classes wouldn't be a bit shorter with interface Common than they would be without. Default methods in interfaces will really shine when it comes to adding new functionality to existing interfaces, something not possible without breaking all implementers of an interface in previous versions of Java.
All of this is based on the as-yet-incomplete Java SE 8 with Lambda. You can download a pre-release build, but be aware that it is a work in progress.

Why would an Enum implement an Interface?

I just found out that Java allows enums to implement an interface. What would be a good use case for that?
Here's one example (a similar/better one is found in Effective Java 2nd Edition):
public interface Operator {
int apply (int a, int b);
}
public enum SimpleOperators implements Operator {
PLUS {
int apply(int a, int b) { return a + b; }
},
MINUS {
int apply(int a, int b) { return a - b; }
};
}
public enum ComplexOperators implements Operator {
// can't think of an example right now :-/
}
Now to get a list of both the Simple + Complex Operators:
List<Operator> operators = new ArrayList<Operator>();
operators.addAll(Arrays.asList(SimpleOperators.values()));
operators.addAll(Arrays.asList(ComplexOperators.values()));
So here you use an interface to simulate extensible enums (which wouldn't be possible without using an interface).
Enums don't just have to represent passive sets (e.g. colours). They can represent more complex objects with functionality, and so you're then likely to want to add further functionality to these - e.g. you may have interfaces such as Printable, Reportable etc. and components that support these.
The Comparable example given by several people here is wrong, since Enum already implements that. You can't even override it.
A better example is having an interface that defines, let's say, a data type. You can have an enum to implement the simple types, and have normal classes to implement complicated types:
interface DataType {
// methods here
}
enum SimpleDataType implements DataType {
INTEGER, STRING;
// implement methods
}
class IdentifierDataType implements DataType {
// implement interface and maybe add more specific methods
}
There is a case I often use. I have a IdUtil class with static methods to work with objects implementing a very simple Identifiable interface:
public interface Identifiable<K> {
K getId();
}
public abstract class IdUtil {
public static <T extends Enum<T> & Identifiable<S>, S> T get(Class<T> type, S id) {
for (T t : type.getEnumConstants()) {
if (Util.equals(t.getId(), id)) {
return t;
}
}
return null;
}
public static <T extends Enum<T> & Identifiable<S>, S extends Comparable<? super S>> List<T> getLower(T en) {
List<T> list = new ArrayList<>();
for (T t : en.getDeclaringClass().getEnumConstants()) {
if (t.getId().compareTo(en.getId()) < 0) {
list.add(t);
}
}
return list;
}
}
If I create an Identifiable enum:
public enum MyEnum implements Identifiable<Integer> {
FIRST(1), SECOND(2);
private int id;
private MyEnum(int id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
Then I can get it by its id this way:
MyEnum e = IdUtil.get(MyEnum.class, 1);
Since Enums can implement interfaces they can be used for strict enforcing of the singleton pattern. Trying to make a standard class a singleton allows...
for the possibility of using reflection techniques to expose private methods as public
for inheriting from your singleton and overriding your singleton's methods with something else
Enums as singletons help to prevent these security issues. This might have been one of the contributing reasons to let Enums act as classes and implement interfaces. Just a guess.
See https://stackoverflow.com/questions/427902/java-enum-singleton and Singleton class in java for more discussion.
It's required for extensibility -- if someone uses an API you've developed, the enums you define are static; they can't be added to or modified. However, if you let it implement an interface, the person using the API can develop their own enum using the same interface. You can then register this enum with an enum manager which conglomerates the enums together with the standard interface.
Edit: #Helper Method has the perfect example of this. Think about having other libraries defining new operators and then telling a manager class that 'hey, this enum exists -- register it'. Otherwise, you'd only be able to define Operators in your own code - there'd be no extensibility.
The post above that mentioned strategies didn't stress enough what a nice lightweight implementation of the strategy pattern using enums gets you:
public enum Strategy {
A {
#Override
void execute() {
System.out.print("Executing strategy A");
}
},
B {
#Override
void execute() {
System.out.print("Executing strategy B");
}
};
abstract void execute();
}
You can have all your strategies in one place without needing a separate compilation unit for each. You get a nice dynamic dispatch with just:
Strategy.valueOf("A").execute();
Makes java read almost like a tasty loosely typed language!
Enums are just classes in disguise, so for the most part, anything you can do with a class you can do with an enum.
I cannot think of a reason that an enum should not be able to implement an interface, at the same time I cannot think of a good reason for them to either.
I would say once you start adding thing like interfaces, or method to an enum you should really consider making it a class instead. Of course I am sure there are valid cases for doing non-traditional enum things, and since the limit would be an artificial one, I am in favour of letting people do what they want there.
Most common usage for this would be to merge the values of two enums into one group and treat them similarly. For example, see how to join Fruits and Vegatables.
For example if you have a Logger enum. Then you should have the logger methods such as debug, info, warning and error in the interface. It makes your code loosely coupled.
One of the best use case for me to use enum's with interface is Predicate filters. It's very elegant way to remedy lack of typness of apache collections (If other libraries mayn't be used).
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
public class Test {
public final static String DEFAULT_COMPONENT = "Default";
enum FilterTest implements Predicate {
Active(false) {
#Override
boolean eval(Test test) {
return test.active;
}
},
DefaultComponent(true) {
#Override
boolean eval(Test test) {
return DEFAULT_COMPONENT.equals(test.component);
}
}
;
private boolean defaultValue;
private FilterTest(boolean defautValue) {
this.defaultValue = defautValue;
}
abstract boolean eval(Test test);
public boolean evaluate(Object o) {
if (o instanceof Test) {
return eval((Test)o);
}
return defaultValue;
}
}
private boolean active = true;
private String component = DEFAULT_COMPONENT;
public static void main(String[] args) {
Collection<Test> tests = new ArrayList<Test>();
tests.add(new Test());
CollectionUtils.filter(tests, FilterTest.Active);
}
}
When creating constants in a jar file, it is often helpful to let users extend enum values. We used enums for PropertyFile keys and got stuck because nobody could add any new ones! Below would have worked much better.
Given:
public interface Color {
String fetchName();
}
and:
public class MarkTest {
public static void main(String[] args) {
MarkTest.showColor(Colors.BLUE);
MarkTest.showColor(MyColors.BROWN);
}
private static void showColor(Color c) {
System.out.println(c.fetchName());
}
}
one could have one enum in the jar:
public enum Colors implements Color {
BLUE, RED, GREEN;
#Override
public String fetchName() {
return this.name();
}
}
and a user could extend it to add his own colors:
public enum MyColors implements Color {
BROWN, GREEN, YELLOW;
#Override
public String fetchName() {
return this.name();
}
}
Another posibility:
public enum ConditionsToBeSatisfied implements Predicate<Number> {
IS_NOT_NULL(Objects::nonNull, "Item is null"),
IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"),
IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative");
private final Predicate<Number> predicate;
private final String notSatisfiedLogMessage;
ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) {
this.predicate = predicate;
this.notSatisfiedLogMessage = notSatisfiedLogMessage;
}
#Override
public boolean test(final Number item) {
final boolean isNotValid = predicate.negate().test(item);
if (isNotValid) {
log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage);
}
return predicate.test(item);
}
}
and using:
Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);
Enums are like Java Classes, they can have Constructors, Methods, etc. The only thing that you can't do with them is new EnumName(). The instances are predefined in your enum declaration.
Here's my reason why ...
I have populated a JavaFX ComboBox with the values of an Enum. I have an interface, Identifiable (specifying one method: identify), that allows me to specify how any object identifies itself to my application for searching purposes. This interface enables me to scan lists of any type of objects (whichever field the object may use for identity) for an identity match.
I'd like to find a match for an identity value in my ComboBox list. In order to use this capability on my ComboBox containing the Enum values, I must be able to implement the Identifiable interface in my Enum (which, as it happens, is trivial to implement in the case of an Enum).
I used an inner enum in an interface describing a strategy to keep instance control (each strategy is a Singleton) from there.
public interface VectorizeStrategy {
/**
* Keep instance control from here.
*
* Concrete classes constructors should be package private.
*/
enum ConcreteStrategy implements VectorizeStrategy {
DEFAULT (new VectorizeImpl());
private final VectorizeStrategy INSTANCE;
ConcreteStrategy(VectorizeStrategy concreteStrategy) {
INSTANCE = concreteStrategy;
}
#Override
public VectorImageGridIntersections processImage(MarvinImage img) {
return INSTANCE.processImage(img);
}
}
/**
* Should perform edge Detection in order to have lines, that can be vectorized.
*
* #param img An Image suitable for edge detection.
*
* #return the VectorImageGridIntersections representing img's vectors
* intersections with the grids.
*/
VectorImageGridIntersections processImage(MarvinImage img);
}
The fact that the enum implements the strategy is convenient to allow the enum class to act as proxy for its enclosed Instance. which also implements the interface.
it's a sort of strategyEnumProxy :P the clent code looks like this:
VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
If it didn't implement the interface it'd had been:
VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);

Enum "does not have a no-arg default constructor" with Jaxb and cxf

A client is having an issue running java2ws on some of their code, which uses & extends classes that are consumed from my SOAP web services. Confused yet? :)
I'm exposing a SOAP web service (JBoss5, Java 6). Someone is consuming that web service with Axis1 and creating a jar out of it with the data types and client stubs. They are then defining their own type, which extends one of my types. My type contains an enumeration.
class MyParent {
private MyEnumType myEnum;
// getters, settters for myEnum;
}
class TheirChild extends MyParent {
...
}
When they are running java2ws on their code (which extends my class), they get
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.foo.bar.MyEnuMType does not have a no-arg default constructor.
this problem is related to the following location:
at net.foo.bar.MyEnumType
at public net.foo.bar.MyEnumType net.foo.bar.MyParent.getMyEnum()
The enum I've defined is below. This is now how it comes out after being consumed, but it's how I have it defined on the app server:
#XmlType(name = "MyEnumType")
#XmlEnum
public enum MyEnumType {
Val1("Val1"),
Val2("Val2")
private final String value;
MyEnumType(String v) {
value = v;
}
public String value() {
return value;
}
public static MyEnumType fromValue(String v) {
if (v == null || v.length() == 0) {
return null;
}
if (v.equals("Val1")) {
return MyEnumType.Val1;
}
if (v.equals("Val2")) {
return MyEnumType.Val2;
}
return null;
}
}
I've seen things online and other posts, like (this one) regarding Jaxb's inability to handle Lists or things like that, but I'm baffled about my enum. I'm pretty sure you can't have a default constructor for an enum (well, at least a public no-arg constructor, Java yells at me when I try), so I'm not sure what makes this error possible. Any ideas?
Also, the "2 counts of IllegalAnnotationsExceptions" may be because my code actually has two enums that are written similarly, but I left them out of this example for brevity.
The no-arg constructor for JAXB doesn't have to be public, it can be private:
private String value;
private MyEnumType() {} // for JAXB
MyEnumType(String v) {
value = v;
}
You can't keep the value member final this way, though.
I am certain you can have a default constructor for an enum.
In fact, that what you have when you don't define a constructor explicitely
(like yours with a String parameter).
You can also have several constructors, one no-args and others.
In the precise example you give, it would be simple to avoid the String parameter altogether.
The provided name() method has exactly the value you are provided.
The code would even be simpler:
#XmlType(name = "MyEnumType")
#XmlEnum
public enum MyEnumType {
Val1, Val2;
public String value() {
return name();
}
public static MyEnumType fromValue(String v) {
for(MyEnumType type : values()) {
if (type.value().equals(v)) {
return type;
}
}
return null;
}
}
If you have really some complex parameters to set to each value, and can't have specific constructors because of a library, you could also store your varying values into an EnumMap, and read this as needed.
when you do from-java-to-wsdl, apache check at first is it enum class or not, and only if this check fail, it check for constructor. You can see it in org.apache.axis.wsdl.fromJava.Types::isBeanCompatible. Any normal man, will think that if he write
public enum MyEnum{}
it will be enough. But Apache developers does not think so (IDK why, may be for some compatibility reasons). They do this method - org.apache.axis.utils.JavaUtils::isEnumClassSub.
If you will decomile this class, you will see, that your enum
MUST implement public String getValue() {return name();}
MUST implement public MyEnum fromString(String v){return valueOf(v);}
CAN'T contain public void setValue(){}
MUST implement String toString(), but each object implement it.

Categories