Changing AutoValue module to Code-Generation
This commit is contained in:
9
code-generation/README.md
Normal file
9
code-generation/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## Code Generation
|
||||
|
||||
This module contains articles about automatic code generation
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Introduction to AutoValue](https://www.baeldung.com/introduction-to-autovalue)
|
||||
- [Introduction to AutoFactory](https://www.baeldung.com/autofactory)
|
||||
- [Google AutoService](https://www.baeldung.com/google-autoservice)
|
||||
53
code-generation/pom.xml
Normal file
53
code-generation/pom.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>code-generation</artifactId>
|
||||
<version>1.0</version>
|
||||
<name>code-generation</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.auto.value</groupId>
|
||||
<artifactId>auto-value</artifactId>
|
||||
<version>${auto-value.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.auto.factory</groupId>
|
||||
<artifactId>auto-factory</artifactId>
|
||||
<version>${auto-factory.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.auto.service</groupId>
|
||||
<artifactId>auto-service</artifactId>
|
||||
<version>${auto-service.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>${guice.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<auto-value.version>1.3</auto-value.version>
|
||||
<auto-factory.version>1.0-beta5</auto-factory.version>
|
||||
<auto-service.version>1.0-rc5</auto-service.version>
|
||||
<guice.version>4.2.0</guice.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.autofactory;
|
||||
|
||||
import com.baeldung.autofactory.model.Camera;
|
||||
import com.baeldung.autofactory.model.Phone;
|
||||
import com.baeldung.autofactory.model.PhoneFactory;
|
||||
import com.baeldung.autofactory.modules.SonyCameraModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
public class App {
|
||||
|
||||
public static void main(String[] args) {
|
||||
PhoneFactory phoneFactory = new PhoneFactory(() -> new Camera("Unknown", "XXX"));
|
||||
Phone simplePhone = phoneFactory.create("other parts");
|
||||
|
||||
Injector injector = Guice.createInjector(new SonyCameraModule());
|
||||
PhoneFactory injectedFactory = injector.getInstance(PhoneFactory.class);
|
||||
Phone xperia = injectedFactory.create("Xperia");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.autofactory;
|
||||
|
||||
import com.baeldung.autofactory.custom.SmartPhone;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public interface CustomStorage {
|
||||
|
||||
SmartPhone customROMInGB(int romSize);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.autofactory.custom;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public abstract class AbstractFactory {
|
||||
|
||||
abstract CustomPhone newInstance(String brand);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.autofactory.custom;
|
||||
|
||||
import com.google.auto.factory.AutoFactory;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
@AutoFactory(extending = AbstractFactory.class)
|
||||
public class CustomPhone {
|
||||
|
||||
private final String brand;
|
||||
|
||||
public CustomPhone(String brand) {
|
||||
this.brand = brand;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.autofactory.custom;
|
||||
|
||||
import com.baeldung.autofactory.CustomStorage;
|
||||
import com.google.auto.factory.AutoFactory;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
@AutoFactory(className = "SamsungFactory", allowSubclasses = true, implementing = CustomStorage.class)
|
||||
public class SmartPhone {
|
||||
|
||||
private int romSize;
|
||||
|
||||
public SmartPhone(int romSize) {
|
||||
this.romSize = romSize;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.autofactory.model;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class Camera {
|
||||
|
||||
private final String manufacturer;
|
||||
private final String serial;
|
||||
|
||||
public Camera(String manufacturer, String serial) {
|
||||
this.manufacturer = manufacturer;
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
public String getManufacturer() {
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
public String getSerial() {
|
||||
return serial;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.autofactory.model;
|
||||
|
||||
import com.google.auto.factory.AutoFactory;
|
||||
import com.google.auto.factory.Provided;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class ClassicPhone {
|
||||
|
||||
private final String dialpad;
|
||||
private final String ringer;
|
||||
private String otherParts;
|
||||
|
||||
@AutoFactory
|
||||
public ClassicPhone(@Provided String dialpad, @Provided String ringer) {
|
||||
this.dialpad = dialpad;
|
||||
this.ringer = ringer;
|
||||
}
|
||||
|
||||
@AutoFactory
|
||||
public ClassicPhone(String otherParts) {
|
||||
this("defaultDialPad", "defaultRinger");
|
||||
this.otherParts = otherParts;
|
||||
}
|
||||
|
||||
public String getDialpad() {
|
||||
return dialpad;
|
||||
}
|
||||
|
||||
public String getRinger() {
|
||||
return ringer;
|
||||
}
|
||||
|
||||
public String getOtherParts() {
|
||||
return otherParts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.autofactory.model;
|
||||
|
||||
import com.google.auto.factory.AutoFactory;
|
||||
import com.google.auto.factory.Provided;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
@AutoFactory
|
||||
public class Phone {
|
||||
|
||||
private Camera camera;
|
||||
private String otherParts;
|
||||
|
||||
public Phone(@Provided @Named("Sony") Camera camera, String otherParts) {
|
||||
this.camera = camera;
|
||||
this.otherParts = otherParts;
|
||||
}
|
||||
|
||||
/* required when used as a base class for AutoFactory */
|
||||
public Phone() {
|
||||
}
|
||||
|
||||
public Camera getCamera() {
|
||||
return camera;
|
||||
}
|
||||
|
||||
public String getOtherParts() {
|
||||
return otherParts;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.autofactory.modules;
|
||||
|
||||
import com.baeldung.autofactory.model.Camera;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class SonyCameraModule extends AbstractModule {
|
||||
|
||||
private static int SONY_CAMERA_SERIAL = 1;
|
||||
|
||||
@Named("Sony")
|
||||
@Provides
|
||||
Camera cameraProvider() {
|
||||
return new Camera("Sony", String.format("%03d", SONY_CAMERA_SERIAL++));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.autofactory.provided;
|
||||
|
||||
import com.baeldung.autofactory.model.Camera;
|
||||
import com.google.auto.factory.AutoFactory;
|
||||
import com.google.auto.factory.Provided;
|
||||
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
@AutoFactory
|
||||
public class IntermediateAssembler {
|
||||
|
||||
private final Provider<Camera> camera;
|
||||
private final String otherParts;
|
||||
|
||||
public IntermediateAssembler(@Provided Provider<Camera> camera, String otherParts) {
|
||||
this.camera = camera;
|
||||
this.otherParts = otherParts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.autofactory.provider;
|
||||
|
||||
import com.baeldung.autofactory.model.Camera;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class SonyCameraProvider implements Provider<Camera> {
|
||||
|
||||
private static int sonyCameraSerial = 1;
|
||||
|
||||
@Override
|
||||
public Camera get() {
|
||||
return new Camera("Sony", String.format("%03d", sonyCameraSerial++));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.autoservice;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@AutoService(TranslationService.class)
|
||||
public class BingTranslationServiceProvider implements TranslationService {
|
||||
@Override
|
||||
public String translate(String message, Locale from, Locale to) {
|
||||
// implementation details
|
||||
return message + " (translated by Bing)";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.autoservice;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@AutoService(TranslationService.class)
|
||||
public class GoogleTranslationServiceProvider implements TranslationService {
|
||||
@Override
|
||||
public String translate(String message, Locale from, Locale to) {
|
||||
// implementation details
|
||||
return message + " (translated by Google)";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.baeldung.autoservice;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public interface TranslationService {
|
||||
String translate(String message, Locale from, Locale to);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.autovalue;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
|
||||
@AutoValue
|
||||
public abstract class AutoValueMoney {
|
||||
public abstract String getCurrency();
|
||||
|
||||
public abstract long getAmount();
|
||||
|
||||
public static AutoValueMoney create(String currency, long amount) {
|
||||
return new AutoValue_AutoValueMoney(currency, amount);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.autovalue;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
|
||||
@AutoValue
|
||||
public abstract class AutoValueMoneyWithBuilder {
|
||||
public abstract String getCurrency();
|
||||
|
||||
public abstract long getAmount();
|
||||
|
||||
static Builder builder() {
|
||||
return new AutoValue_AutoValueMoneyWithBuilder.Builder();
|
||||
}
|
||||
|
||||
@AutoValue.Builder
|
||||
abstract static class Builder {
|
||||
abstract Builder setCurrency(String currency);
|
||||
|
||||
abstract Builder setAmount(long amount);
|
||||
|
||||
abstract AutoValueMoneyWithBuilder build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.autovalue;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class Foo {
|
||||
private final String text;
|
||||
private final int number;
|
||||
|
||||
public Foo(String text, int number) {
|
||||
this.text = text;
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(text, number);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Foo [text=" + text + ", number=" + number + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Foo other = (Foo) obj;
|
||||
if (number != other.number)
|
||||
return false;
|
||||
if (text == null) {
|
||||
if (other.text != null)
|
||||
return false;
|
||||
} else if (!text.equals(other.text))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.baeldung.autovalue;
|
||||
|
||||
public final class ImmutableMoney {
|
||||
private final long amount;
|
||||
private final String currency;
|
||||
|
||||
public ImmutableMoney(long amount, String currency) {
|
||||
this.amount = amount;
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) (amount ^ (amount >>> 32));
|
||||
result = prime * result + ((currency == null) ? 0 : currency.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ImmutableMoney other = (ImmutableMoney) obj;
|
||||
if (amount != other.amount)
|
||||
return false;
|
||||
if (currency == null) {
|
||||
if (other.currency != null)
|
||||
return false;
|
||||
} else if (!currency.equals(other.currency))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImmutableMoney [amount=" + amount + ", currency=" + currency + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.autovalue;
|
||||
|
||||
public class MutableMoney {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MutableMoney [amount=" + amount + ", currency=" + currency + "]";
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public void setCurrency(String currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
private long amount;
|
||||
private String currency;
|
||||
|
||||
public MutableMoney(long amount, String currency) {
|
||||
super();
|
||||
this.amount = amount;
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
}
|
||||
13
code-generation/src/main/resources/logback.xml
Normal file
13
code-generation/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.autoservice;
|
||||
|
||||
import com.baeldung.autoservice.TranslationService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TranslationServiceUnitTest {
|
||||
|
||||
private ServiceLoader<TranslationService> loader;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
loader = ServiceLoader.load(TranslationService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenServiceLoaderLoads_thenLoadsAllProviders() {
|
||||
long count = StreamSupport.stream(loader.spliterator(), false).count();
|
||||
assertEquals(2, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenServiceLoaderLoadsGoogleService_thenGoogleIsLoaded() {
|
||||
TranslationService googleService = StreamSupport.stream(loader.spliterator(), false)
|
||||
.filter(p -> p.getClass().getSimpleName().equals("GoogleTranslationServiceProvider"))
|
||||
.findFirst()
|
||||
.get();
|
||||
|
||||
String message = "message";
|
||||
assertEquals(message + " (translated by Google)", googleService.translate(message, null, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.autovalue;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class MoneyUnitTest {
|
||||
@Test
|
||||
public void givenTwoSameValueMoneyObjects_whenEqualityTestFails_thenCorrect() {
|
||||
MutableMoney m1 = new MutableMoney(10000, "USD");
|
||||
MutableMoney m2 = new MutableMoney(10000, "USD");
|
||||
assertFalse(m1.equals(m2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoSameValueMoneyValueObjects_whenEqualityTestPasses_thenCorrect() {
|
||||
ImmutableMoney m1 = new ImmutableMoney(10000, "USD");
|
||||
ImmutableMoney m2 = new ImmutableMoney(10000, "USD");
|
||||
assertTrue(m1.equals(m2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValueTypeWithAutoValue_whenFieldsCorrectlySet_thenCorrect() {
|
||||
AutoValueMoney m = AutoValueMoney.create("USD", 10000);
|
||||
assertEquals(m.getAmount(), 10000);
|
||||
assertEquals(m.getCurrency(), "USD");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void given2EqualValueTypesWithAutoValue_whenEqual_thenCorrect() {
|
||||
AutoValueMoney m1 = AutoValueMoney.create("USD", 5000);
|
||||
AutoValueMoney m2 = AutoValueMoney.create("USD", 5000);
|
||||
assertTrue(m1.equals(m2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void given2DifferentValueTypesWithAutoValue_whenNotEqual_thenCorrect() {
|
||||
AutoValueMoney m1 = AutoValueMoney.create("GBP", 5000);
|
||||
AutoValueMoney m2 = AutoValueMoney.create("USD", 5000);
|
||||
assertFalse(m1.equals(m2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void given2EqualValueTypesWithBuilder_whenEqual_thenCorrect() {
|
||||
AutoValueMoneyWithBuilder m1 = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("USD").build();
|
||||
AutoValueMoneyWithBuilder m2 = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("USD").build();
|
||||
assertTrue(m1.equals(m2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void given2DifferentValueTypesBuilder_whenNotEqual_thenCorrect() {
|
||||
AutoValueMoneyWithBuilder m1 = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("USD").build();
|
||||
AutoValueMoneyWithBuilder m2 = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("GBP").build();
|
||||
assertFalse(m1.equals(m2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValueTypeWithBuilder_whenFieldsCorrectlySet_thenCorrect() {
|
||||
AutoValueMoneyWithBuilder m = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("USD").build();
|
||||
assertEquals(m.getAmount(), 5000);
|
||||
assertEquals(m.getCurrency(), "USD");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user