Initialising Enum members using Spring - spring

I have and Enum like below.
public enum MyEnum {
ENUM1("ENUM1Code", "ENUM1 Desc"), ENUM2("ENUM2Code", "ENUM2"), ENUM3("ENUM3Code", "ENUM3");
private String code;
private String description;
private MyEnum(String code, String description) {
this.code = code;
this.description = description;
}
public String getCode() {
return code;
}
public String getDescription() {
return description;
}
}
Can anybody suggest me how to remove the initialisation from this Enum and perform it through Spring ?
Thanks in advance
Dileep

You can't because enum are static objects.
You can externalize code/description and manage them manually.
EDIT:
I can't see need to use Spring for this type of jobs; you can achieve the same goal with easy code (a bit of Spring is used, the PropertiesLoaderUtils utility class).
Create a properties file where you store, for every enum, code and description and write utility code to read data; result of your custom code is a UDT like that:
class EnumWithData implements Serializable {
MyEnum enumValue;
String code;
String description;
// Write properties get/set
// Equals check for enumValue only
boolean equals(Object other) {
EnumWithData b = (EnumWithData)other;
return b.enumValue == this.enumValue;
}
}
abstract class EnumWithDataUtility {
private static Properties definition = PropertiesLoaderUtils.loadProperties("path/to/resource");
public final static EnumWithData getEnumWithData(MyEnum enumValue) {
EnumWithData udt = new EnumWithData();
udt.enumValue = enumValue;
...
return udt;
}
}

Related

Return the built Enum to JSON

I have an object and an enum for it. When I give away an object, I want my enum inside the object to be displayed as an object with the name and value attributes without using DTO, or to be partially used. I want json to build this object itself (enum with name and value), and I give only the object in which this enum is contained.
public enum MyType {
TT("Time Tu"), TD("Time dust");
MyType(String value) {
this.value = value;
}
private String value;
public String getValue() {
return value;
}
#Override
public String toString() {
return value;
}
Here is the DTO, it may be necessary (get/set/constructor auto generated by Intellij Idea)
public class MyTypeWrapper {
private String name;
private String value;
}
#Entity
public class MyObject {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
private String number;
........
private MyType myType;
........
}
Perhaps serialization/deserialization is needed? How to do it?
It should go something like this:
{
.....
myType: {
"name: "TT",
"value: "TD"
},
.....
}
Perhaps this is a piece of the solution? But I'm not sure that it will work, and it's not clear how to serialize
public enum MyType {
......
#JsonValue
private MyTypeWrapper getWrapper()
return new MyTypeWrapper(this.name, this.value)
}
......
}
This turned out to be the solution
public enum MyType {
......
#JsonValue
private MyTypeWrapper getWrapper()
return new MyTypeWrapper(this.name, this.value)
}
......
}

How to implement the custom converter for a field using Spring Data Elasticsearch?

I need to implement a custom converter in spring data elastic-search. I need to concatenate something to the text when saving and retrieving. I have seen a similar question is here. And in the answer is says it is implemented now and available. But I didn't found any example how to implement it. So anybody know how to do this?
You can find examples in the test code of the library.
You have to create a converter:
class FooConverter implements PropertyValueConverter {
public static final String PREFIX = "foo-";
#Override
public Object write(Object value) {
return PREFIX + value.toString();
}
#Override
public Object read(Object value) {
String valueString = value.toString();
if (valueString.startsWith(PREFIX)) {
return valueString.substring(PREFIX.length());
} else {
return value;
}
}
}
and then register it for the property of your entity class:
#Document(indexName = "foo")
class Entity {
#Field(type = FieldType.Text)
#ValueConverter(FooConverter.class)
private String someField;
// ...
}

How to use Java 8 Optional with Moxy and Jersey

Is it possible to use Jersey with Moxy to/from Json and Java 8 Optionals?
How to configure it?
You can declare following class:
public class OptionalAdapter<T> extends XmlAdapter<T, Optional<T>> {
#Override
public Optional<T> unmarshal(T value) throws Exception {
return Optional.ofNullable(value);
}
#Override
public T marshal(Optional<T> value) throws Exception {
return value.orElse(null);
}
}
And use like this:
#XmlRootElement
public class SampleRequest {
#XmlElement(type = Integer.class)
#XmlJavaTypeAdapter(value = OptionalAdapter.class)
private Optional<Integer> id;
#XmlElement(type = String.class)
#XmlJavaTypeAdapter(value = OptionalAdapter.class)
private Optional<String> text;
/* ... */
}
Or declare in package-info.java and remove #XmlJavaTypeAdapter from POJOs:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlJavaTypeAdapters({
#XmlJavaTypeAdapter(type = Optional.class, value = OptionalAdapter.class)
})
But here are some drawbacks:
Adapter above can only work with simple types like Integer, String, etc. that can be parsed by MOXY by default.
You have to specify #XmlElement(type = Integer.class) explicitly to tell the parser type are working with, otherwise null values would be passed to adapter's unmarshal method.
You miss the opportunity of using adapters for custom types, e.g. custom adapter for java.util.Date class based on some date format string. To overcome this you'll need to create adapter something like class OptionalDateAdapter<String> extends XmlAdapter<String, Optional<Date>>.
Also using Optional on field is not recommended, see this discussion for details.
Taking into account all the above, I would suggest just using Optional as return type for your POJOs:
#XmlRootElement
public class SampleRequest {
#XmlElement
private Integer id;
public Optional<Integer> getId() {
return Optional.ofNullable(id);
}
public void setId(Integer id) {
this.id = id;
}
}

How to wrap Iterator value into simple java class

I am new in java .I want to wrap the value of result in simple java class.
Iterator<Map<String,Object>> result=template.query(cypher,params);
Any Help will be Appreciated.
If you're using the template.query then you can either have it mapped to a domain entity or to the Map (and then you build the POJO yourself).
Otherwise, you can use a #Query in a repository and map it to a query result class.
For example
#Query("MATCH (user:User) WHERE user.gender={0} RETURN user.name AS UserName, user.gender AS UserGender, user.account as UserAccount, user.deposits as UserDeposits")
Iterable<RichUserQueryResult> findUsersByGender(Gender gender);
#QueryResult
public class RichUserQueryResult {
private Gender userGender;
private String userName;
private BigInteger userAccount;
private BigDecimal[] userDeposits;
public Gender getUserGender() {
return userGender;
}
public String getUserName() {
return userName;
}
public BigInteger getUserAccount() {
return userAccount;
}
public BigDecimal[] getUserDeposits() {
return userDeposits;
}
}

Mixed Entity and Business classes - Refactor help needed

I have a project where Entity Classes and Business classes are mixed up. The entity beans are part of the business and all is used through the whole project.
How can I best refactor those classes to separate those layers. I also want to keep the changes to the implementers as minimal as possible. Preferable no changes, otherwise hundreds of references need to be updated.
How should I rename the classes and work through this?
Example of mixed code:
// Mixed business-entity class
public final class Language {
private final Long id;
private final String code;
private final String description;
//Constructor
public Language() {
}
//getters and setters
public String getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
...
//Business is a part of this class
public static Language findByUser(User user) {
Language language;
...implementation to find user language...
return language;
}
....
}
// Implementing class
public class Messenger {
public Messenger() {
}
public static void sendEmail() {
...
Language emailLanguage = Language.findByUser(user):
...
}
}
I want to separte those layers in:
// Entity Class
public final class Language {
private final Long id;
private final String code;
private final String description;
//Constructor
public Language() {
}
//getters and setters
public String getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
...
}
// Business Class
public final class LanguageImpl {
public LanguageImpl() {
}
public static Language findByUser(User user) {
Language language;
...implementation to find user language...
return language;
}
....
}
Provide minimal changes to implementation classes, preferable no changes. Otherwise a lot of work will come because of the references all over the code-base.
// Implementing class
public class Messenger {
public Messenger() {
}
public static void sendEmail() {
...
Language emailLanguage = Language.findByUser(user);
...
}
}
How do I work through this refactoring?
How should I rename my classes?
Any thoughts would be very helpful! Thanks!
This is my solution. Please review and accept this if it looks good. Thanks!
The mixed business-entity class is re-used as a wrapper class. This makes it possible to re-use this in all implementing classes where no changes are needed.
public final class Language Extends LanguageImpl{
private final LanguageEntity languageEntity;
//Constructor
public Language(LanguageEntity le) {
languageEntity = le;
}
//Wrapper method
public static Language findByUser(User user) {
LanguageEntity le = findEntityByUser(user);
Language language = new Language(le);
return language;
}
....
}
A new Entity class is created (LanguageEntity) in a new package. This avoids package and naming conflicts with the original mixed class (Language). All entity fields and methods from the mixed class are moved here.
package com.test.entity;
public final class LanguageEntity {
private final Long id;
private final String code;
private final String description;
//Constructor
public LanguageEntity() { }
//getters and setters
public String getId() { return this.id; }
public void setId(Long id) { this.id = id; }
...
}
A new business class is created (LanguageImpl) in a new package. All business methods are moved here. The original mixed class will extend this new business class.
package com.test.impl
public final class LanguageImpl {
//Constructor
public LanguageImpl() { }
//Business is a part of this class
public static LanguageEntity findEntityByUser(User user) {
LanguageEntity language;
...implementation to find user language...
return language;
}
....
}
This is an implementing class that does not need changes. Hundreds of implementation locations remain unchanged, which saves a lot of work. Hurray!
public class Messenger {
public Messenger() { }
public static void sendEmail() {
...
Language emailLanguage = Language.findByUser(user):
...
}
}
And for future development, the new combination LanguageEntity and LanguageImpl will be used. The original Language will be deprecated.
Please leave comments on this solution. Other solutions are more than welcome!

Resources