项目作者: gabrie-allaigre

项目描述 :
Simply create Java Bean
高级语言: Java
项目地址: git://github.com/gabrie-allaigre/component-bean.git
创建时间: 2017-06-02T16:53:25Z
项目社区:https://github.com/gabrie-allaigre/component-bean

开源协议:Other

下载


Component-Bean

Description

Component-Bean allows:

  • Simplify the creation of Java Bean
  • No need to write hashcode, equals, toString and serialization
  • Methods for easier access to properties
  • They make it possible to make multiple inheritance.
  • Automatic creation of a Builder and the list of fields
  • Creation of Dto and the mapper

To use it, add the dependency in the ‘pom.xml’ of the project:

Usage

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.talanlabs</groupId>
  4. <artifactId>component-bean</artifactId>
  5. <version>1.0.1</version>
  6. </dependency>
  7. </dependencies>

Annotation Engine

To use the annation engine, you must add in the plugins of the Maven pom:

  1. <plugin>
  2. <groupId>org.bsc.maven</groupId>
  3. <artifactId>maven-processor-plugin</artifactId>
  4. <version>2.2.1</version>
  5. <executions>
  6. <execution>
  7. <id>process</id>
  8. <phase>generate-sources</phase>
  9. <goals>
  10. <goal>process</goal>
  11. </goals>
  12. <configuration>
  13. <processors>
  14. <processor>com.talanlabs.component.annotation.processor.ComponentBeanProcessor</processor>
  15. </processors>
  16. </configuration>
  17. </execution>
  18. </executions>
  19. <dependencies>
  20. <dependency>
  21. <groupId>com.talanlabs</groupId>
  22. <artifactId>component-bean-apt</artifactId>
  23. <version>1.0.1</version>
  24. </dependency>
  25. </dependencies>
  26. </plugin>

The base

Create an ICountry interface that implements the class IComponent:

  1. @ComponentBean
  2. public interface ICountry extends IComponent {
  3. }

We will see later the role of the announcement @ComponentBean

Then we can add the getter and setter of a field ‘code’ and a field ‘meaning’:

  1. @ComponentBean
  2. public interface ICountry extends IComponent {
  3. String getCode();
  4. void setCode(String code);
  5. String getMeaning();
  6. void setMeaning(String meaning);
  7. }

Now we can create a Main class, which will create an instance and fill in the fields:

  1. ICountry country = ComponentFactory.getInstance().createInstance(ICountry.class);
  2. country.setCode("FRA");
  3. country.setMeaning("France");
  4. System.out.println(country);

Or with the @ComponentBean annotation, a builder class has been created.

  1. ICountry country = CountryBuilder.newBuilder().code("FRA").meaning("France").build();
  2. System.out.println(country);

The hashcode and the equals are automatically managed by adding the annotation @EqualsKey in front of the getter.

  1. @ComponentBean
  2. public interface ICountry extends IComponent {
  3. @EqualsKey
  4. String getCode();
  5. void setCode(String code);
  6. String getMeaning();
  7. void setMeaning(String meaning);
  8. }
  1. ICountry country1 = CountryBuilder.newBuilder().code("FRA").meaning("France").build();
  2. ICountry country2 = CountryBuilder.newBuilder().code("FRA").meaning("Italie").build();
  3. ICountry country3 = CountryBuilder.newBuilder().code("ESP").meaning("Espagne").build();
  4. System.out.println(country1.equals(country2)); // true
  5. System.out.println(country1.equals(country3)); // false

You can add multiple @EqualsKey to have multiple keys. It contains a parameter nullEquals, by default it istrue, it allows to accept or not the comparison null == null.

We can add multiple inheritance, this allows to add fields easily:

  1. @ComponentBean
  2. public interface ICountry extends IGeolocalisation, INommage, IComponent {
  3. ...

The @Computed annotation is used to create a calculated method. The annotation takes a class in parameter. It will be instantiated only once.
You can change the way you instantiate it by changing ComponentFactory.getInstance (). SetComputedFactory
It can take parameters. If the method starts with get will be considered as a getter and will look for a setter. It is proposed in the list of properties.

  1. @ComponentBean
  2. public interface ICountry extends IComponent {
  3. @EqualsKey
  4. String getCode();
  5. void setCode(String code);
  6. String getMeaning();
  7. void setMeaning(String meaning);
  8. @Computed(CountryComputed.class)
  9. String total();
  10. @Computed(CountryComputed.class)
  11. String total(String separator);
  12. }

The Computed class must contain the same method, same name, same return type. In first parameter the class of origin and then the parameters of the method to be computed.

  1. public class CountryComputed {
  2. public String total(ICountry country) {
  3. return total(country, " ");
  4. }
  5. public String total(ICountry country, String separator) {
  6. return country.getCode() + separator + country.getMeaning();
  7. }
  8. }
  1. ICountry country = CountryBuilder.newBuilder().code("FRA").meaning("France").build();
  2. System.out.println(country.total());
  3. System.out.println(country.total(" - "));

Default Java 8

Instead of using Computed, it is possible to do default methods

  1. @ComponentBean
  2. public interface ICountry extends IComponent {
  3. @EqualsKey
  4. String getCode();
  5. void setCode(String code);
  6. String getMeaning();
  7. void setMeaning(String meaning);
  8. default String total() {
  9. return total( " ");
  10. }
  11. default String total(String separator) {
  12. return country.getCode() + separator + country.getMeaning();
  13. }
  14. }

Accessors

To read a value from a property you can either use the getter that matches either straightGetProperty or straightGetProperties

  1. System.out.println(country.getCode());
  2. System.out.println(country.straightGetProperty("code"));
  3. System.out.println(country.straightGetProperties().get("code"));

To avoid using String for property names, the @ComponentBean annotation creates a Class Fields

  1. System.out.println(country.straightGetProperty(CountryFields.code().name()));
  2. System.out.println(country.straightGetProperty(CountryFields.code));

If you have an ICity class that contains an ICountry:

  1. @ComponentBean
  2. public interface ICity extends IComponent {
  3. ...
  4. ICountry getCountry();
  5. void setCountry(ICountry country);
  6. ...
  7. }

From CityFields you can get the ICountry code

  1. System.out.println(CityFields.country().dot().code().name()); // "country.code"
  2. ComponentHelper.getValue(city, CityFields.country().dot().code().name());

To write a value

  1. country.setCode("FRA");
  2. country.straightSetProperty(CountryFields.code().name(), "FRA");
  3. Map<String, Object> map = country.straightGetProperties();
  4. map.put(CountryFields.code().name(), "FRA");
  5. country.straightSetProperties(map);

Know the list of properties and their type

  1. System.out.println(country.straightGetPropertyNames());
  2. System.out.println(country.straightGetPropertyClass(CountryFields.code().name()));

The list of properties contains all getter (normal, default or computed)

You can also use the ComponentDescriptor from the class:

  1. System.out.println(ComponentFactory.getInstance().isComponentType(country)); // true
  2. Class<ICountry> componentClass = ComponentFactory.getInstance().getComponentClass(country);
  3. ComponentDescriptor cd = ComponentFactory.getInstance().getDescriptor(ICountry.class);
  4. ComponentDescriptor cd = ComponentFactory.getInstance().getDescriptor(country);

From the ComponentDescriptor one can have access to all the properties.

  1. cd.getPropertyDescriptors();
  2. cd.getPropertyDescriptor(CityFields.country);

ToStringFactory

The toString of Component can be changed from ToStringFactory:

  1. ComponentFactory.setInstance(new ComponentFactory(ComponentFactoryConfigurationBuilder.newBuilder().toStringFactory(IToStringFactory.simple()).build()));

There are 3 default factory types:

Class Usage Description
SimpleToStringFactory IToStringFactory.simple() Displays only the name of the Component and its hashcode
CompleteToStringFactory IToStringFactory.complete() By default displays a line with the name of the Component, its hashcode and all the fields, in order the EqualsKey then in alphabetical order
CompleteToStringFactory new CompleteToStringFactory(...) Allows to customize the Complete: hidden the Header, multiline, hide the null values, change the order of display of fields, include / exclude fields …
ClassToStringFactory new ClassToStringFactory(defaultToStringFactory) Allows you to specify the toString according to the Component: classToStringFactory.put(IMonComponent.class,monToStringFactory)

For the sorting of fields, it is possible to cumulate the sorting:

Class Usage Description
None IPropertyComparator.natural() Fields are sorted alphabetically
EqualsKeyPropertyComparator IPropertyComparator.equalsKey() The @EqualsKey fields are first
FirstPropertyComparator IPropertyComparator.first(propertyNames) The given fields will be put first
FirstPropertyComparator IPropertyComparator.first(componentClass) The fields contained in the ComponentClass will be put first
LastPropertyComparator IPropertyComparator.last(propertyNames) The given fields will be set last
LastPropertyComparator IPropertyComparator.last(componentClass) The fields contained in the ComponentClass will be set last
NullValuePropertyComparator IPropertyComparator.nullsLast() Null fields are set last
NullValuePropertyComparator IPropertyComparator.nullsFirst() Null fields are listed first
None IPropertyComparator.compose(propertyComparators) Fields are sorted according to the order of the comparators

Example:

  1. // In order first the EqualsKey, "version", and last the fields of ITracable and the null values ​​and each group sorted in alphabetical order
  2. IPropertyComparator defaultPropertyComparator = IPropertyComparator
  3. .compose(IPropertyComparator.equalsKey(), IPropertyComparator.first(EntityFields.version), IPropertyComparator.last(ITracable.class), new NullValuePropertyComparator(),
  4. IPropertyComparator.natural());