Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
+ refactoring
- Loading branch information
Showing
15 changed files
with
596 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,37 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<artifactId>immutables</artifactId> | |||
<groupId>org.immutables</groupId> | |||
<version>2.0-SNAPSHOT</version> | |||
</parent> | |||
<artifactId>builder</artifactId> | |||
<name>${project.groupId}.${project.artifactId}</name> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.immutables.dependency</groupId> | |||
<artifactId>utility</artifactId> | |||
<version>${project.version}</version> | |||
<type>pom</type> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.immutables</groupId> | |||
<artifactId>testing</artifactId> | |||
<version>${project.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.immutables</groupId> | |||
<artifactId>value-standalone</artifactId> | |||
<version>${project.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.immutables</groupId> | |||
<artifactId>value</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
</dependencies> | |||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,117 @@ | |||
package org.immutables.builder; | |||
|
|||
import java.lang.annotation.Documented; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
import org.immutables.value.Value.Immutable; | |||
import org.immutables.value.Value.Style; | |||
|
|||
/** | |||
* <em> | |||
* This umbrella annotaion does nothing. Use nested annotations, such as {@literal @}{@code Builder.Factory} | |||
* to generate builders for arbitrary static factory methods. | |||
* and is used for static factory methods to generate arbitrary builders. | |||
* Immutable values as {@link Immutable Value.Immutable} generate builder by default, unless | |||
* turned off using {@literal @}{@link Immutable#builder() Value.Immutable(builder=false)}</em> | |||
* @see Factory | |||
*/ | |||
@Target({}) | |||
public @interface Builder { | |||
/** | |||
* Annotate static factory methods that produce some value (non-void, non-private) to create | |||
* builder out of constructor parameters. | |||
* | |||
* <pre> | |||
* class Sum { | |||
* {@literal @}Builder.Factory | |||
* static Integer sum(int a, int b) { | |||
* return a + b; | |||
* } | |||
* } | |||
* ... // use generated builder | |||
* Integer result = new SumBuilder() | |||
* .a(111) | |||
* .b(222) | |||
* .build(); | |||
* </pre> | |||
* <p> | |||
* Class level and package level style annotations fully supported (see {@link Style}). | |||
*/ | |||
@Documented | |||
@Retention(RetentionPolicy.SOURCE) | |||
@Target(ElementType.METHOD) | |||
public @interface Factory {} | |||
|
|||
/** | |||
* Factory method parameter might be turned into builder parameter using this annotation. | |||
* | |||
* <pre> | |||
* class NodeFactory { | |||
* {@literal @}Builder.Factory | |||
* static Node node({@literal @}Builder.Parameter Object value, Optional<Node> left, Optional<Node> right) { | |||
* return ... | |||
* } | |||
* } | |||
* ... // notice the constructor parameter generated | |||
* Integer result = new NodeBuilder(new Object()) | |||
* .left(node1) | |||
* .right(node2) | |||
* .build(); | |||
* </pre> | |||
*/ | |||
@Documented | |||
@Retention(RetentionPolicy.SOURCE) | |||
@Target(ElementType.PARAMETER) | |||
public @interface Parameter {} | |||
|
|||
/** | |||
* Applicable only to enum parameters, this annotation turns parameters into switcher methods on | |||
* builder. Each switcher method applies corresponding constant value. Switch methods are named | |||
* after parameter name prefixed with properly cased (case transformed) enum constant name. | |||
* | |||
* <pre> | |||
* class BulbFactory { | |||
* enum Switcher { | |||
* OFF, ON | |||
* } | |||
* {@literal @}Builder.Factory | |||
* static Bulb bulb({@literal @}Builder.Switch Switcher light) { | |||
* return ... | |||
* } | |||
* } | |||
* ... // notice the switcher methods instead of enum initializer | |||
* Bulb b = new BulbBuilder() | |||
* .onLight() // set to Switcher.ON | |||
* .offLight() // set to Switcher.OFF | |||
* .build(); | |||
* </pre> | |||
* <p> | |||
* If proper {@link #defaultOrdinal()} value is specified, then one of the state will be | |||
* considered the default. If no default is specified then it is mandatory to call switcher method | |||
* once, otherwise switcher method may be omitted. | |||
* | |||
* <pre> | |||
* class BulbFactory { | |||
* enum Switcher { | |||
* OFF, ON | |||
* } | |||
* {@literal @}Builder.Factory | |||
* static Bulb bulb({@literal @}Builder.Switch(defaultOrdinal = 0) Switcher light) { | |||
* return ... | |||
* } | |||
* } | |||
* ... // notice no 'onLight' generated | |||
* Bulb b = new BulbBuilder() // default is Switcher.OFF | |||
* .onLight() // set to Switcher.ON | |||
* .build(); | |||
* </pre> | |||
*/ | |||
@Documented | |||
@Retention(RetentionPolicy.SOURCE) | |||
@Target(ElementType.PARAMETER) | |||
public @interface Switch { | |||
int defaultOrdinal() default -1; | |||
} | |||
} |
42 changes: 42 additions & 0 deletions
42
builder/test/org/immutables/builder/fixture/FactoryBuilderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,42 @@ | |||
/* | |||
Copyright 2014 Immutables Authors and Contributors | |||
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 org.immutables.builder.fixture; | |||
|
|||
import org.immutables.builder.fixture.ConcatBuilder; | |||
import org.immutables.builder.fixture.SumBuilder; | |||
import java.lang.reflect.Modifier; | |||
import org.junit.Test; | |||
import static org.immutables.check.Checkers.*; | |||
|
|||
public class FactoryBuilderTest { | |||
|
|||
@Test | |||
public void generatedPublicAsOfStyleAnnotation() { | |||
check(Modifier.isPublic(SumBuilder.class.getModifiers())); | |||
check(Modifier.isPublic(ConcatBuilder.class.getModifiers())); | |||
} | |||
|
|||
@Test(expected = IllegalStateException.class) | |||
public void missingAttributesCheck() { | |||
new SumBuilder().build(); | |||
} | |||
|
|||
@Test | |||
public void invokesStaticFactory() { | |||
check(new SumBuilder().a(2).b(3).build()).is(5); | |||
check(new ConcatBuilder().addNumbers(1, 2).addStrings("a", "b").build()).isOf("a", "b", 1, 2); | |||
} | |||
} |
53 changes: 53 additions & 0 deletions
53
builder/test/org/immutables/builder/fixture/FactoryParametersAndSwitcherTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,53 @@ | |||
package org.immutables.builder.fixture; | |||
|
|||
import org.immutables.builder.fixture.Factory1Builder; | |||
import org.immutables.builder.fixture.Factory2Builder; | |||
import org.immutables.builder.fixture.Factory3Builder; | |||
import org.immutables.builder.fixture.Factory4Builder; | |||
import org.immutables.builder.fixture.Factory5Builder; | |||
import java.lang.annotation.RetentionPolicy; | |||
import org.junit.Test; | |||
import static org.immutables.check.Checkers.*; | |||
|
|||
public class FactoryParametersAndSwitcherTest { | |||
|
|||
@Test | |||
public void parameters() { | |||
|
|||
check(new Factory1Builder(null) | |||
.theory(1) | |||
.reality("1") | |||
.build()).is("1 != 1, null"); | |||
|
|||
check(new Factory2Builder(2, "2").build()).is("2 != 2"); | |||
|
|||
check(Factory3Builder.newBuilder(3).reality("3").build()).is("3 != 3"); | |||
} | |||
|
|||
@Test | |||
public void switcher() { | |||
|
|||
check(Factory4Builder.newBuilder(4) | |||
.runtimePolicy() | |||
.sourcePolicy() | |||
.classPolicy() | |||
.build()).is("" + RetentionPolicy.CLASS + 4); | |||
|
|||
check(Factory4Builder.newBuilder(42) | |||
.sourcePolicy() | |||
.runtimePolicy() | |||
.build()).is("" + RetentionPolicy.RUNTIME + 42); | |||
|
|||
try { | |||
Factory4Builder.newBuilder(44).build(); | |||
check(false); | |||
} catch (IllegalStateException ex) { | |||
} | |||
} | |||
|
|||
@Test | |||
public void switcherDefaults() { | |||
check(Factory5Builder.newBuilder().build()).is("" + RetentionPolicy.SOURCE.toString()); | |||
check(Factory5Builder.newBuilder().runtimePolicy().build()).is("" + RetentionPolicy.RUNTIME); | |||
} | |||
} |
39 changes: 39 additions & 0 deletions
39
builder/test/org/immutables/builder/fixture/FactoryParametersAndSwitchers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,39 @@ | |||
package org.immutables.builder.fixture; | |||
|
|||
import java.lang.annotation.RetentionPolicy; | |||
import javax.annotation.Nullable; | |||
import org.immutables.builder.Builder; | |||
import org.immutables.value.Value; | |||
|
|||
@Value.Style | |||
class FactoryParameters { | |||
@Builder.Factory | |||
public static String factory1(int theory, String reality, @Nullable @Builder.Parameter Void evidence) { | |||
return theory + " != " + reality + ", " + evidence; | |||
} | |||
|
|||
@Builder.Factory | |||
public static String factory2(@Builder.Parameter int theory, @Builder.Parameter String reality) { | |||
return theory + " != " + reality; | |||
} | |||
|
|||
} | |||
|
|||
@Value.Style(builder = "newBuilder") | |||
class FactoryParametersAndSwitchers { | |||
|
|||
@Builder.Factory | |||
public static String factory3(@Builder.Parameter int theory, String reality) { | |||
return theory + " != " + reality; | |||
} | |||
|
|||
@Builder.Factory | |||
public static String factory4(@Builder.Parameter int value, @Builder.Switch RetentionPolicy policy) { | |||
return policy + "" + value; | |||
} | |||
|
|||
@Builder.Factory | |||
public static String factory5(@Builder.Switch(defaultOrdinal = 0) RetentionPolicy policy) { | |||
return policy.toString(); | |||
} | |||
} |
71 changes: 71 additions & 0 deletions
71
builder/test/org/immutables/builder/fixture/ImprovisedFactories.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,71 @@ | |||
/* | |||
Copyright 2014 Immutables Authors and Contributors | |||
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 org.immutables.builder.fixture; | |||
|
|||
import org.immutables.builder.fixture.ConcatBuilder; | |||
import org.immutables.builder.fixture.SumBuilder; | |||
import org.immutables.builder.fixture.SuperstringBuilder; | |||
import com.google.common.collect.Iterables; | |||
import java.util.List; | |||
import java.util.SortedSet; | |||
import javax.annotation.Nullable; | |||
import org.immutables.builder.Builder; | |||
import org.immutables.value.Value; | |||
|
|||
/** | |||
* Builders for simple attributes, collection, generic and primitive variations. | |||
* Builders are public as of style annotation. | |||
*/ | |||
class ImprovisedFactories { | |||
|
|||
@Builder.Factory | |||
public static String superstring(int theory, String reality, @Nullable Void evidence) { | |||
return theory + " != " + reality + ", " + evidence; | |||
} | |||
|
|||
@Builder.Factory | |||
public static Iterable<Object> concat(List<String> strings, @Value.NaturalOrder SortedSet<Integer> numbers) { | |||
return Iterables.<Object>concat(strings, numbers); | |||
} | |||
|
|||
@Builder.Factory | |||
public static int sum(int a, int b) { | |||
return a + b; | |||
} | |||
|
|||
void use() { | |||
|
|||
int sumOf1and2 = new SumBuilder() | |||
.a(1) | |||
.b(2) | |||
.build(); | |||
|
|||
String superstring = new SuperstringBuilder() | |||
.theory(0) | |||
.reality("") | |||
.evidence(null) | |||
.build(); | |||
|
|||
Iterable<Object> concat = new ConcatBuilder() | |||
.addStrings(superstring) | |||
.addNumbers(4, 2, 3) | |||
.build(); | |||
|
|||
concat.toString(); | |||
|
|||
String.valueOf(sumOf1and2); | |||
} | |||
} |
Oops, something went wrong.