overriding class methods: including the superclass method in the subclass method JAVA - subclass

So I have these to classes, one is my superclass the other is my subclass. I am having trouble calling my sub class method in my superclass method so I can get these results also. the methods are overloading and I am having a problem understanding it. I think If I can get this, it will help me understand how the two interlink and work.
I am having trouble in my copy constructor, toString method and equals method in my subclass
Superclass:
public class Car
{
private String make;
private String model;
private int miles;
// The default constructor—use this
public Car()
{
this.make=null;
this.model=null;
this.miles=0;
}
// The 3-parameter constructor –use this
public Car(String make,String model,int miles)
{
this.make=make;
this.model=model;
this.miles=miles;
}
// The copy constructor—use this
public Car(Car obj)
{
this.make=obj.make;
this.model=obj.model;
this.miles=obj.miles;
}
// The toString method—use this
public String toString()
{
String str;
str = "The car Brand: "+ this.make +" Mobel: "+this.model+" miles on the car: "+this.miles;
return str;
}
// The equals method—use this
public boolean equals(Car obj)
{
if (this.make.equals(obj.make)&&this.model.equals(obj.model)&&this.miles==obj.miles)
return true;
else
return false;
}
}
//My subclass method
public class Convertible extends Car
{
private String typeTop;
// The default constructor—use this
public Convertible()
{
super();
this.typeTop= null;
}
// The 4-parameter constructor—use this
public Convertible(String make, String model,int miles,String typeTop)
{
super(make,model,miles);
this.typeTop=typeTop;
}
// The copy constructor—use this
public Convertible(Convertible obj)
{
super(Convertible obj);
this.typeTop=obj.typeTop;
}
// The toString method—use this
public String toString()
{
String str;
str =super.toString()+this.typeTop;
return str;
}
// The equals method—use this
public boolean equals(Convertible obj)
{
if(super.equals(super.obj)&&this.typeTop.equals(obj.typeTop))
return true;
else
return false;
}
}

change line number 29 in Convertible class to super(obj);
and 43 to if (super.equals(obj) && this.typeTop.equals(obj.typeTop)) {

Related

Trying to bind request parameters to nested object with spring controller using the dot notation and I keep getting a bad request error

I have searched and everything seems to say as long as you use spring 4+ I should be able to use dot notation to bind request parameters to a pojo.
This is what my request looks like:
And this is what my controller looks like:
And my dto:
I even tried adding #RequestParam("p.page") int page in the controller to make sure my endpoint was getting hit and it does. Am I missing something obvious or am I not allowed to use dot notation to populate a pojo with a spring controller?
And the parent class:
public class JhmPageableDto
{
private String query;
private int page;
private int size;
private String sort;
private boolean sortAsc;
public String getQuery()
{
return query;
}
public void setQuery(String query)
{
this.query = query;
}
public int getPage()
{
return page;
}
public void setPage(int page)
{
this.page = page;
}
public int getSize()
{
return size;
}
public void setSize(int size)
{
this.size = size;
}
public String getSort()
{
return sort;
}
public void setSort(String sort)
{
this.sort = sort;
}
public boolean isSortAsc()
{
return sortAsc;
}
public void setSortAsc(boolean sortAsc)
{
this.sortAsc = sortAsc;
}
}

How to properly implement a Spring Converter?

I have a Money class with factory methods for numeric and String values. I would like to use it as a property of my input Pojos.
I created some Converters for it, this is the String one:
#Component
public class StringMoneyConverter implements Converter<String, Money> {
#Override
public Money convert(String source) {
return Money.from(source);
}
}
My testing Pojo is very simple:
public class MoneyTestPojo {
private Money value;
//getter and setter ommited
}
I have an endpoint which expects a Pojo:
#PostMapping("/pojo")
public String savePojo(#RequestBody MoneyTestPojo pojo) {
//...
}
Finally, this is the request body:
{
value: "100"
}
I have the following error when I try this request:
JSON parse error: Cannot construct instance of
br.marcellorvalle.Money (although at least one Creator
exists): no String-argument constructor/factory method to deserialize
from String value ('100'); nested exception is
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot
construct instance of br.marcellorvalle.Money (although at
least one Creator exists): no String-argument constructor/factory
method to deserialize from String value ('100')\n at [Source:
(PushbackInputStream); line: 8, column: 19] (through reference chain:
br.marcellorvalle.MoneytestPojo[\"value\"])",
If I change Money and add a constructor which receives a String this request works but I really need a factory method as I have to deliver special instances of Money on specific cases (zeros, nulls and empty strings).
Am I missing something?
Edit: As asked, here goes the Money class:
public class Money {
public static final Money ZERO = new Money(BigDecimal.ZERO);
private static final int PRECISION = 2;
private static final int EXTENDED_PRECISION = 16;
private static final RoundingMode ROUNDING = RoundingMode.HALF_EVEN;
private final BigDecimal amount;
private Money(BigDecimal amount) {
this.amount = amount;
}
public static Money from(float value) {
return Money.from(BigDecimal.valueOf(value));
}
public static Money from(double value) {
return Money.from(BigDecimal.valueOf(value));
}
public static Money from(String value) {
if (Objects.isNull(value) || "".equals(value)) {
return null;
}
return Money.from(new BigDecimal(value));
}
public static Money from(BigDecimal value) {
if (Objects.requireNonNull(value).equals(BigDecimal.ZERO)) {
return Money.ZERO;
}
return new Money(value);
}
//(...)
}
Annotating your factory method with #JsonCreator (from the com.fasterxml.jackson.annotation package) will resolve the issue:
#JsonCreator
public static Money from(String value) {
if (Objects.isNull(value) || "".equals(value)) {
return null;
}
return Money.from(new BigDecimal(value));
}
I just tested it, and it worked for me. Rest of your code looks fine except for the sample request (value should be in quotes), but I guess that's just a typo.
Update 1:
If you're unable to make changes to the Money class, I can think of another option - a custom Jackson deserializer:
public class MoneyDeserializer extends StdDeserializer<Money> {
private static final long serialVersionUID = 0L;
public MoneyDeserializer() {
this(null);
}
public MoneyDeserializer(Class<?> vc) {
super(vc);
}
#Override
public Money deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
String value = node.textValue();
return Money.from(value);
}
}
Just register it with your ObjectMapper.
It seems that using the org.springframework.core.convert.converter.Converter only works if the Money class is a "#PathVariable" in the controller.
I finally solved it using the com.fasterxml.jackson.databind.util.StdConverter class:
I created the following Converter classes:
public class MoneyJsonConverters {
public static class FromString extends StdConverter<String, Money> {
#Override
public Money convert(String value) {
return Money.from(value);
}
}
public static class ToString extends StdConverter<Money, String> {
#Override
public String convert(Money value) {
return value.toString();
}
}
}
Then I annotated the Pojo with #JsonDeserialize #JsonSerialize accordingly:
public class MoneyTestPojo {
#JsonSerialize(converter = MoneyJsonConverters.ToString.class)
#JsonDeserialize(converter = MoneyJsonConverters.FromString.class)
private Money value;
//getter and setter ommited
}

How can I refactor this method? (spring + java8)

I am trying to refactor the Java class below. I have a method that saves a POJO (entity) depending on which instance it belongs to.
The code below shows only 3 services but there is 13 service in total.
Each service is calling a separate *RepositoryImpl.
For instance, the ActiviteService is an interface and the activiteService.create(activity) will call the implementation of that interface.
#Autowired
private ActiviteService activiteService;
#Autowired
private AdresseMsSanteService adresseMsSanteService;
#Autowired
private AttributionParticuliereService attributionParticuliereService;
private boolean sauvegarder(Object object, Long idIdPlay, String game,
Integer gameIndex) {
boolean isSaved = false;
if (idIdPlay == null) {
throw new IllegalArgumentException("IdPlay id is null");
}
if (object instanceof Activite) {
Activite activite = (Activite) object;
activite.setIdIdPlay(idIdPlay);
if (this.isGameOn(activite, game, gameIndex)) {
activiteService.create(activite);
isSaved = true;
}
} else if (object instanceof AdresseMsSante) {
AdresseMsSante adresseMsSante = (AdresseMsSante) object;
adresseMsSante.setIdIdPlay(idIdPlay);
if (this.isGameOn(adresseMsSante, game, gameIndex)) {
adresseMsSanteService.create(adresseMsSante);
isSaved = true;
}
} else if (object instanceof AttributionParticuliere) {
AttributionParticuliere attributionParticuliere = (AttributionParticuliere) object;
attributionParticuliere.setIdIdPlay(idIdPlay);
if (this.isGameOn(attributionParticuliere, game, gameIndex)) {
attributionParticuliereService.create(attributionParticuliere);
isSaved = true;
}
} else if
Firstly, I would create an interface representing your Game Entity. For instance:
public interface GameEntity {
void setIdIdPlay(Long idIdPlay);
}
After that, you create the classes that implement the GameEntity interface:
#Entity
#Table
public class AdresseMsSante implements GameEntity {
#Id
Long idIdPlay;
public void setIdIdPlay(Long idIdPlay) {
this.idIdPlay = idIdPlay;
}
}
#Entity
#Table
public class Activite implements GameEntity {
#Id
Long idIdPlay;
public void setIdIdPlay(Long idIdPlay) {
this.idIdPlay = idIdPlay;
}
}
Then, create your generic repository which will save every Game Entity.
#Repository
public class Repo {
#Autowired
EntityManager entityManager;
#Transactional
public void save(GameEntity obj) {
entityManager.merge(obj);
}
}
Finally, your method will be like that:
#Autowired
Repo repo;
private boolean sauvegarder(Object object, Long idIdPlay, String game,
Integer gameIndex) {
boolean isSaved = false;
if (idIdPlay == null) {
throw new IllegalArgumentException("IdPlay id is null");
}
GameEntity gameEntity = (GameEntity) object;
gameEntity.setIdIdPlay(idIdPlay);
if(this.isGameOn(gameEntity, game, gameIndex)) {
repo.save(gameEntity);
isSaved = true;
}
return isSaved;
}
boolean isGameOn(GameEntity gameEntity, String game, Integer gameIndex) {
// do something
return true;
}

Spring -Mongodb storing/retrieving enums as int not string

My enums are stored as int in mongodb (from C# app). Now in Java, when I try to retrieve them, it throws an exception (it seems enum can be converted from string value only). Is there any way I can do it?
Also when I save some collections into mongodb (from Java), it converts enum values to string (not their value/cardinal). Is there any override available?
This can be achieved by writing mongodb-converter on class level but I don't want to write mondodb-converter for each class as these enums are in many different classes.
So do we have something on the field level?
After a long digging in the spring-mongodb converter code,
Ok i finished and now it's working :) here it is (if there is simpler solution i will be happy see as well, this is what i've done ) :
first define :
public interface IntEnumConvertable {
public int getValue();
}
and a simple enum that implements it :
public enum tester implements IntEnumConvertable{
vali(0),secondvali(1),thirdvali(5);
private final int val;
private tester(int num)
{
val = num;
}
public int getValue(){
return val;
}
}
Ok, now you will now need 2 converters , one is simple ,
the other is more complex. the simple one (this simple baby is also handling the simple convert and returns a string when cast is not possible, that is great if you want to have enum stored as strings and for enum that are numbers to be stored as integers) :
public class IntegerEnumConverters {
#WritingConverter
public static class EnumToIntegerConverter implements Converter<Enum<?>, Object> {
#Override
public Object convert(Enum<?> source) {
if(source instanceof IntEnumConvertable)
{
return ((IntEnumConvertable)(source)).getValue();
}
else
{
return source.name();
}
}
}
}
the more complex one , is actually a converter factory :
public class IntegerToEnumConverterFactory implements ConverterFactory<Integer, Enum> {
#Override
public <T extends Enum> Converter<Integer, T> getConverter(Class<T> targetType) {
Class<?> enumType = targetType;
while (enumType != null && !enumType.isEnum()) {
enumType = enumType.getSuperclass();
}
if (enumType == null) {
throw new IllegalArgumentException(
"The target type " + targetType.getName() + " does not refer to an enum");
}
return new IntegerToEnum(enumType);
}
#ReadingConverter
public static class IntegerToEnum<T extends Enum> implements Converter<Integer, Enum> {
private final Class<T> enumType;
public IntegerToEnum(Class<T> enumType) {
this.enumType = enumType;
}
#Override
public Enum convert(Integer source) {
for(T t : enumType.getEnumConstants()) {
if(t instanceof IntEnumConvertable)
{
if(((IntEnumConvertable)t).getValue() == source.intValue()) {
return t;
}
}
}
return null;
}
}
}
and now for the hack part , i personnaly didnt find any "programmitacly" way to register a converter factory within a mongoConverter , so i digged in the code and with a little casting , here it is (put this 2 babies functions in your #Configuration class)
#Bean
public CustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
converters.add(new IntegerEnumConverters.EnumToIntegerConverter());
// this is a dummy registration , actually it's a work-around because
// spring-mongodb doesnt has the option to reg converter factory.
// so we reg the converter that our factory uses.
converters.add(new IntegerToEnumConverterFactory.IntegerToEnum(null));
return new CustomConversions(converters);
}
#Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setApplicationContext(appContext);
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
mongoConverter.setCustomConversions(customConversions());
ConversionService convService = mongoConverter.getConversionService();
((GenericConversionService)convService).addConverterFactory(new IntegerToEnumConverterFactory());
mongoConverter.afterPropertiesSet();
return mongoConverter;
}
You will need to implement your custom converters and register it with spring.
http://static.springsource.org/spring-data/data-mongo/docs/current/reference/html/#mongo.custom-converters
Isn't it easier to use plain constants rather than an enum...
int SOMETHING = 33;
int OTHER_THING = 55;
or
public class Role {
public static final Stirng ROLE_USER = "ROLE_USER",
ROLE_LOOSER = "ROLE_LOOSER";
}
String yourRole = Role.ROLE_LOOSER

How to test Singleton class that has a static dependency

I have a Singleton class that uses the thread-safe Singleton pattern from Jon Skeet as seen in the TekPub video. The class represents a cached list of reference data for dropdowns in an MVC 3 UI.
To get the list data the class calls a static method on a static class in my DAL.
Now I'm moving into testing an I want to implement an interface on my DAL class but obviously cannot because it is static and has only one static method so there's no interface to create. So I want to remove the static implementation so I can do the interface.
By doing so I can't call the method statically from the reference class and because the reference class is a singleton with a private ctor I can't inject the interface. How do I get around this? How do I get my interface into the reference class so that I can have DI and I can successfully test it with a mock?
Here is my DAL class in current form
public static class ListItemRepository {
public static List<ReferenceDTO> All() {
List<ReferenceDTO> fullList;
... /// populate list
return fullList;
}
}
This is what I want it to look like
public interface IListItemRepository {
List<ReferenceDTO> All();
}
public class ListItemRepository : IListItemRepository {
public List<ReferenceDTO> All() {
List<ReferenceDTO> fullList;
... /// populate list
return fullList;
}
}
And here is my singleton reference class, the call to the static method is in the CheckRefresh call
public sealed class ListItemReference {
private static readonly Lazy<ListItemReference> instance =
new Lazy<ListItemReference>(() => new ListItemReference(), true);
private const int RefreshInterval = 60;
private List<ReferenceDTO> cache;
private DateTime nextRefreshDate = DateTime.MinValue;
public static ListItemReference Instance {
get { return instance.Value; }
}
public List<SelectListDTO> SelectList {
get {
var lst = GetSelectList();
lst = ReferenceHelper.AddDefaultItemToList(lst);
return lst;
}
}
private ListItemReference() { }
public ReferenceDTO GetByID(int id) {
CheckRefresh();
return cache.Find(item => item.ID == id);
}
public void InvalidateCache() {
nextRefreshDate = DateTime.MinValue;
}
private List<SelectListDTO> GetSelectList() {
CheckRefresh();
var lst = new List<SelectListDTO>(cache.Count + 1);
cache.ForEach(item => lst.Add(new SelectListDTO { ID = item.ID, Name = item.Name }));
return lst;
}
private void CheckRefresh() {
if (DateTime.Now <= nextRefreshDate) return;
cache = ListItemRepository.All(); // Here is the call to the static class method
nextRefreshDate = DateTime.Now.AddSeconds(RefreshInterval);
}
}
}
You can use the singleton based on instance(not based on static), for which you can declare interface like this.
public interface IListItemRepository
{
List<ReferenceDTO> All();
}
public class ListItemRepository : IListItemRepository
{
static IListItemRepository _current = new ListItemRepository();
public static IListItemRepository Current
{
get { return _current; }
}
public static void SetCurrent(IListItemRepository listItemRepository)
{
_current = listItemRepository;
}
public List<ReferenceDTO> All()
{
.....
}
}
Now, you can mock IListItemRepository to test.
public void Test()
{
//arrange
//If Moq framework is used,
var expected = new List<ReferneceDTO>{new ReferneceDTO()};
var mock = new Mock<IListItemRepository>();
mock.Setup(x=>x.All()).Returns(expected);
ListItemRepository.SetCurrent(mock.Object);
//act
var result = ListItemRepository.Current.All();
//Assert
Assert.IsSame(expected, result);
}
Which DI framework are you using? Depending on your answer, IOC container should be able to handle single-instancing so that you don't have to implement your own singleton pattern in the caching class. In your code you would treat everything as instanced classes, but in your DI framework mappings you would be able to specify that only one instance of the cache class should ever be created.
One way to test it would be if you refactor your ListItemReference by adding extra property:
public sealed class ListItemReference {
...
public Func<List<ReferenceDTO>> References = () => ListItemRepository.All();
...
private void CheckRefresh() {
if (DateTime.Now <= nextRefreshDate) return;
cache = References();
nextRefreshDate = DateTime.Now.AddSeconds(RefreshInterval);
}
}
And then in your test you could do:
ListItemReference listReferences = new ListItemReference();
listReferences.References = () => new List<ReferenceDTO>(); //here you can return any mock data
Of course it's just temporary solution and I would recommend getting rid of statics by using IoC/DI.

Resources