Which design pattern should be used in this use case? - java

I am working on app where I have to write custom validation on some xmlbean oject, basically to see so and so fields with proper values exist or not. Now those objects are generated from diff schema. I am using validation provided by xmlbeans against the schema but there are some more business validation needs to be done for these objects before it is being processed further.
Can somebody suggest any design pattern for this use case?
Thanks

Define your own validator interface:
interface Validator <T extends XmlBean> {
boolean validate(T bean);
}
Implement it for each classyou are dealing with, you can provide a factory class to get the validator for each bean class by implementing the following interface:
interface IValidatorFactory {
public <T extends XmlBean> Validator<T> getValidator(Class<T> clazz);
}
class ValidatorFactory implements IValidatorFactory {
private final Map<Class<? extends XmlBean>, Validator<? extends XmlBean>> map =
new HashMap<Class<? extends XmlBean>, Validator<? extends XmlBean>>();
#SuppressWarnings("unchecked")
#Override
public <T extends XmlBean> Validator<T> getValidator(Class<T> clazz) {
return (Validator<T>)map.get(clazz);
}
public <T extends XmlBean> void registerValidator(Class<T> clazz, Validator<T> validator) {
map.put(clazz, validator);
}
}

You could potentially add your own custom pre- and post-set hooks to your generated XmlBeans classes. To add add the hooks you need to create an .xsdconfig file and provide a some preSet() and postSet() static methods that can be called.
For an example, see:
https://www.ibm.com/developerworks/xml/library/x-xmlbeanse/?ca=dgr-eclipse-1
And also:
http://svn.apache.org/viewvc/xmlbeans/trunk/test/cases/xbean/extensions/prePostFeature/readOnlyBean/po.xsdconfig?revision=HEAD&view=markup
http://svn.apache.org/viewvc/xmlbeans/trunk/test/src/xmlobject/extensions/prePostFeature/readOnlyBean/existing/FooHandler.java?revision=HEAD&view=markup

Related

Implements a Factory Pattern in java with using Generics

I need help with Java Generics.
My model is: I have some classes that extends a Dto (Data Transfer Object) and some classes that extends Entity (The model of my object to DB).
I have
interface Mapper<D extends Dto, E extends Entity>{
//Convert a Entity to Dto.
D toDto(E entity);
And I have some classes that implements this interface (i.e PersonMapper, BookMapper and so far and so on).
#Component
public class PersonMapper implements Mapper<PersonDto, PersonEntity> {
//implementation
}
#Component
public class BookMapper implements Mapper<BookDto, BookEntity> {
//implementation
}
What I want to do is to use Factory Pattern in order to select at runtime my Mapper, that depends from a String that I pass in input.
#Autowired
private PersonMapper personMapper;
#Autowired
private BookMapper bookMapper;
public <D extends Dto, E extends Entity> Mapper<D, E> selectMapper(String entity){
if ("Person".equalsIgnoreCase(entity))
return personMapper;
if("Book".equalsIgnoreCase(entity))
return bookMapper;
...
}
With this situation I have the following compile error:
Type mismatch: cannot convert from PersonMapper to Mapper<D,E>
My solutions:
1)
return (Mapper<D, E>) personMapper;
but I have a Warning:
Type Safety: `Unchecked class from personMapper to Mapper<D,H>`
2)
Using WildCard and castingb
public Mapper<Dto, Entity> selectMapper(String entity){
Mapper<? extends Dto, ? extends Entity> toReturn = null;
if ("Person".equalsIgnoreCase(entity))
toReturn = personMapper;
else if("Book".equalsIgnoreCase(entity))
toReturn = bookMapper;
...
return (Mapper<Dto, Entity>) toReturn;
}
But in this case but I have another time a Warning:
Type safety: Unchecked cast from Mapper<capture#29-of ? extends Dto,capture#30-of ? extends Entity> to Mapper<Dto,Entity>
It works but it doesn't seems to be a clean solution
3) Using wildcard as return type:
public Mapper<? extends Dto, ? extends HistoryEntity> selectMapper(String entity)
but you know, using wildcard as return type is not recommended at all and also doesn't help me because I would like to use this mapper and call mapper.toDto ensuring that the return type is an something that extends Dto.
====================================================================
I don't explain why If I write a class constructor like that
public Service<D extends Dto, E extends Entity>{
public Service(Mapper<D,E> mapper){
this.mapper = mapper;
}
}
and than I inject (for example) bookMapper it works.
If, instead, the Mapper<D,E> is in return type I cannot do such a kind of operation.
====================================================================
The help that I ask to you is:
how can I write a solution using clean code principles (avoiding compile warnings, sonarlint issue etc.) in order to implement this kind of logic?
Thank you very much, I appreciate a lot if you dedicate a little bit of your time helping me to solve my problem.
Those vars (D and E) about the caller and not about your code. The D and E are decided by the caller, so there is absolutely no way to guarantee that PersonDTO fits.
Make that Mapper<? extends DTO, ? extends Entity> (and no variables), and given that those are already the lower bounds, just Mapper<?, ?> - that'll work, you can write your return statements without any casts and without compiler errors or warnings.
Of course, it means the caller has a mostly useless type.
Generics are entirely 'compile time / write time' based. The JVM (java.exe) has no idea what generics are, and in fact most of them don't survive the compilation process. The one and only purpose of generics is to make the compiler flag incorrect code and avoid some casting, that is all.
The nature of turning that string into a Mapper is entirely runtime.
Ergo, if Mapper<?, ?> isn't sufficient, what you want isn't possible. You'd need to write compile/write-time checkable stuff, so the moment you use a String, it's impossible. For example, a method getPersonMapper() can of course return a Mapper<PersonDTO, PersonEntity>, no problem.
More generally (heh) it sounds like you're badly reinventing various wheels here. Look at tutorials of JDBI, JOOQ, and Hibernate to get some ideas about how java code is commonly written to interact with databases.
Factory Pattern is pattern that assemble or create something by factory methods, in you case what you need is just to get corresponding mapper by name, so there is a simple way to do that since the mapper beans are autowired, adding String getName() to Mapper interface then implements it for earch implementation, e.g. in BookMapper
#Override
public String getName() { return "Book"; }
use mapper name as key and mapper bean as value to store mapper beans in a map, then you can retrieve it by its name:
#Service
public class SimpleService {
private BookMapper bookMapper;
private PersonMapper personMapper;
private Map<String, Mapper<? extends DTO, ? extends Entity>> mappers = new HashMap<>();
public SimpleService(BookMapper bookMapper, PersonMapper personMapper) {
this.bookMapper = bookMapper;
this.personMapper = personMapper;
mappers.put(bookMapper.getName(), bookMapper);
mappers.put(personMapper.getName(), personMapper);
}
public Mapper<? extends DTO, ? extends Entity> getMapperByName(String mapperName) {
return mappers.get(mapperName);
}
}
and you can cast it to corresponding mapper without warning.
PersonMapper p = (PersonMapper) simpleService.getMapperByName("Person");
or you can put different mapper in their service and use the service to handle you biz likes codes below, after all, you need specified mappers to do specified operations:
if(personThings){
personService.doSomeThing();
}
if(bookThings){
bookService.doSomething();
}

can guice create a factory for me?

I have the following factory class:
public class MessagePresenterCreator implements IPresenterFactory{
#Override
public MessagePresenter createPresenter(Message m) {
if (m instanceof Letter) {
return new LetterPresenter();
}
if (m instanceof Cable) {
return new CablePresenter();
}
if (m instanceof Postcard) {
return new PostcardPresenter();
}
throw new IllegalArgumentException();
}
}
Can I configure a guice to auto-generate and supply such factory by the following interface:
public interface IPresenterFactory {
public abstract MessagePresenter createPresenter(Message m);
}
I like to think of factories in two ways - factories that merely assemble objects from components, and factories that do conditional logic in that assembly.
Your factories have logic behind them. Guice can't automate that logic, because it simply handles the wiring up of dependencies. If you have a type that is created that needs some amount of injected dependencies and some things that are provided just at creation time, then the auto-wiring of factories can be done with guice's AssistedInject extension. This would let you give a factory interface, annotate any fields in the created type with #AssistedInject, and guice's extension would create a factory implementation class which would inject anything bound in the Injector, and also pass through those create() parameters. But in such a case, all Guice and AssistedInject are doing is pulling pieces together - wiring things up according to a recipe specified in advance. It's not making decisions about them at the last minute.
You're providing conditional creation of objects. That's not going to work.
An idea above mentions making a factory that depends on mapping of type to presenter - something like:
Map<Class<? extends Message>, Class<? extends MessagePresenter>>
This is a good approach, if you combine it with Multibinder's MapBindings. (I gotta beef up those docs... hmm)
With this approach you can create an extensible factory - defining the initial mappings of Message -> MessagePresenter subclasses, but leave the possibility open for additional mappings later without having to change your factory - just bind more mappings on the multibinder, like so:
MapBinder<String, Snack> mapbinder = MapBinder.newMapBinder(
binder(),
new TypeLiteral<Class<? extends Message>>(){},
new TypeLiteral<Class<? extends MessagePresenter>>(){});
mapbinder.addBinding(MyMessage.class).toInstance(MyMessagePresenter.class);
mapbinder.addBinding(YourMessage.class).toInstance(YourMessagePresenter.class);
And you can do this in as many modules as you like, adding more types between which to switch, using the mapping.
No guice does not have a factory like that built in. You could write a factory that took a Map<Class<? extends Message>, Class<? extends MessagePresenter> and have that use reflection. That way you can manage it in a guice module if that is your goal.
public class MessagePresenterCreator implements IPresenterFactory{
private final Map<Class<? extends Message>, Class<? extends MessagePresenter> mapping;
public MessagePresenterCreator(Map<Class<? extends Message>, Class<? extends MessagePresenter> mapping) {
this.mapping = mapping;
}
#Override
public MessagePresenter createPresenter(Message m) {
Class<? extends MessagePresenter> clazz = mapping.get(m);
if (clazz == null) {
throw new UnsupportedOperationException();
}
return clazz.newInstance();
}
}

How do I bind a Generic class?

When I try to mock a Dao using Jukito I get the following exception:
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.jukito.JukitoModule.addKeyDependency(JukitoModule.java:338)
at org.jukito.JukitoModule.addInjectionPointDependencies(JukitoModule.java:330)
at org.jukito.JukitoModule.addDependencies(JukitoModule.java:313)
The object I try to mock is a ConcreteDao.
public class ConcreteDao extends AbstractDao<MyDomain> {
}
public abstract class AbstractDao<T extends DatastoreObject> {
}
I read several posts on SO about this binding generics but I can't figure out a way to use TypeLiteral for my binding.
This is what I tried:
bind(new TypeLiteral<AbstractDao<MyDomain>>(){}).to(ConcreteDao.class);
You need to bind like this:
bind(new TypeLiteral<AbstractDao<MyDomain>>(){}).to(new TypeLiteral<ConcreteDao<MyDomain>>(){});
This is how you can retrieve the generic class:
class AbstractDao {
protected final Class<T> clazz;
#Inject
public AbstractDao(TypeLiteral<T> type) {
clazz = (Class<T>) type.getRawType();
}
}
Subclasses of AbstractDao will need to pass entity specific TypeLiterals to the parent class (AbstractDao):
class ConcreteDao extends AbstractDao<MyDomain> {
#Inject
public ConcreteDao(TypeLiteral<MyDomain> type) {
super(type);
}
}
Note that you can make your AbstractDao class non-abstract and implement basic CRUD operations, so that you can use it without the need to extend AbstractDao for each entity. You will just need a binding for each entity like this:
bind(new TypeLiteral<GenericDao<User>>(){}).in(Scopes.SINGLETON);
See my blog-post for more information.

Dao Registry refactoring

Using the generic dao pattern, I define the generic interface:
public interface GenericDao<T extends DataObject, ID extends Serializable> {
T save(T t);
void delete(ID id);
T findById(ID id);
Class<T> getPersistentClass();
}
I then implemented an default GenericDaoImpl implementation to perform these functions with the following constructor:
public GenericDaoImpl(Class<T> clazz) {
this.persistentClass = clazz;
DaoRegistry.getInstance().register(clazz, this);
}
The point of the DaoRegistry is to look up a Dao by the class associating to it. This allows me to extend GenericDaoImpl and overwrite methods for objects that requires special handling:
DaoRegistry.getInstance().getDao(someClass.getClass()).save(someClass);
While it works, there are a few things that I don't like about it:
DaoRegistry is an singleton
The logic of calling save is complicated
Is there a better way to do this?
Edit
I am not looking to debate whether Singleton is an anti-pattern or not.
First of all, what is your problem with DaoRegistry being singleton?
Anyway, you could have an abstract base class for your entities that'd implement save like this
public T save(){
DaoRegistry.getInstance().getDao(this.getClass()).save(this);
}
then you could simply call someEntity.save()
Or it may be more straightforward if the entity classes itself implemented the whole GenericDao interface (save, delete and find methods), so the contents of your GenericDaoImpl would be in the base class of your entities.
It could be better to use instance of DaoRegistry instead of static methods. It would make it more manageable for test configurations. You could implement it as
#Component("daoRegistry")
public class DaoRegistry {
#Autowired
private List<GenericDao> customDaos;
private GenericDao defaultDao = new GenericDaoImpl();
public <T> T getDao(Class<T> clazz) {
// search customDaos for matching clazz, return default dao otherwise
}
}
Also you could add save method to it and rename accordingly. All customised daos should be available as beans.

Using guice to pass in a run-time parameter to constructor

If I have the following class:
public class ObjectDAOMongoDBImpl<T> extends GenericDAOMongoDBImpl<T, ObjectId> implements ObjectDAO<T> {
public ObjectDAOMongoDBImpl(Class<T> entityClass, Mongo mongo, Morphia morphia, String dbName) {
super(entityClass, mongo, morphia, dbName);
}
}
Where, entityClass is provided at run-time - how can I use guice to bind the said type to an interface?
public class RunnerModule extends AbstractModule {
#Override
protected void configure() {
bind(GenericDAO.class).to(ObjectDAOMongoDBImpl.class);
}
}
public class Runner<T, V> {
GenericDAO<T, V> dao;
#Inject
public Runner(GenericDAO<T, V> dao) {
this.dao = dao;
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new RunnerModule());
injector.getInstance(Runner.class);
}
}
It's fine to define mongo, morphia, and dbName as literals to RunnerModule (is there a cleaner way?), but I have no way of knowing what entityClass is until runtime.
This isn't doable with Guice idiomatically, and it isn't its primary focus either.
jfpoilpret have said everything that can be said, but I would like to approach the problem from another direction, where you have the option to (possibly) solve your problem by losing type-safety.
So, in your code, you ask Guice to get an instance of your Runner<T, V> class like this
injector.getInstance(Runner.class);
but this can't be resolved by Guice, because Runner<T, V> has a dependency on GenericDAO<T, V>, but you didn't bind an exact implementation for it. So as jfpoilpret has said, you have to bind some concrete implementations for it in your module.
I'm guessing that you want to determine the exact GenericDAO<T, V> implementation that you pass to your Runner<T, V> based on some input data, which data's type isn't known at compile time. Now, let's assume you have two implementations.
bind(new TypeLiteral<GenericDAO<String, ObjectID>>(){}).to(StringDAO.class);
bind(new TypeLiteral<GenericDAO<Double, ObjectID>>(){}).to(IntegerDAO.class);
Based on different type of inputs you can do this
Injector injector = Guice.createInjector(new RunnerModule());
// possible input which you get from *somewhere* dynamically
Object object = 1.0;
TypeLiteral<?> matchedTypeLiteral = null;
for (Key<?> key : injector.getAllBindings().keySet()) {
TypeLiteral<?> typeLiteral = key.getTypeLiteral();
Type type = typeLiteral.getType();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getRawType() == GenericDAO.class) {
List<Type> actualTypeArguments = Arrays.asList(parameterizedType.getActualTypeArguments());
if (actualTypeArguments.get(0) == object.getClass())
matchedTypeLiteral = typeLiteral;
}
}
};
Runner<?, ?> runner = new Runner<>((GenericDAO<?, ?>) injector.getInstance(Key.get(matchedTypeLiteral)));
System.out.println(runner.dao.getClass()); // IntegerDAO.class
If Object object = "string";, then the other implementation will be found. This is of course rather ugly and can be improved with checking for sub-classes and stuff, but I think you get the idea. The bottom-line is that you can't get around this.
If you manage to do it (getting around it), please drop me an e-mail because I would like to know about it! I had faced the same problem as you're facing not too long ago. I've written a simple BSON codec where I wanted to load specific implementations of a generic interface based on the type of some arbitrary input. This worked well with Java-to-BSON mappings, but I couldn't do it the other way around in any sensible way, so I've opted for a simpler solution.
The way you wrote it, entityClass can only be Object.class (== Class<Object>), and nothing else.
Hence, first of all, your ObjectDAOMongoDBImpl should be generic:
public class ObjectDAOMongoDBImpl<T>
extends GenericDAOMongoDBImpl<T, ObjectId> ...
That part of the problem is related to java, not Guice.
Now for Guice part, you need to define a binding including the generic types, ie by using Guice TypeLiteral:
bind(new TypeLiteral<GenericDAO<T, V>>(){}).to(...);
where T and V must be known in the code above (can't just be generic parameters there).
Looking at this question may also give you further details related to your situation.
This question is a bit old, but I've recently ran into a similar problem, and managed to solve it quite elegantly by adding a tiny extra layer, a factory.
Consider the following repository:
public interface Repository<T extends Model<T>> {
void save(T t);
T load(long key);
}
class SomeDbRepositoryImpl<T extends Model<T>> implements Repository<T> {
private final SomeDbConnection db;
private final Class<T> type;
RepositoryImpl(final Class<T> type, final SomeDbConnection db) {
this.db = db;
this.type = type;
}
...
}
Then, suppose I have a service that needs an instance of Repository<User>. My first try was to try to make Guice pass an instance of Repository<User> in the constructor, and then I'd bind it somehow. The problem is that I really don't want to have to add repository bindings and providers for each model. If I were to do that, the code would look like this:
// Won't work.
class MyService {
private final Repository<User> userRepository;
#Inject MyService(final Repository<User> userRepository) {
this.userRepository = userRepository;
}
...
}
What I ended up doing is creating a RepositoryFactory class, which is not generic by itself, but it contains a generic method.
public interface RepositoryFactory {
<T extends Model<T>> Repository<T> getRepository(Class<T> type);
}
class SomeDbRepositoryFactoryImpl implements RepositoryFactory {
private final SomeDbConnection db;
#Inject SomeDbRepositoryFactoryImpl(final SomeDbConnection db) {
this.db = db;
#Override <T extends Model<T>> Repository<T> getRepository(Class<T> type) {
return new SomeDbRepositoryImpl(type, db);
}
}
So, this is completely type-safe, and I don't have to add a binding for each module. The service that uses a Repository would then look like:
class MyService {
private final Repository<User> userRepository;
#Inject MyService(final RepositoryFactory f) {
this.userRepository = f.getRepository(User.class);
}
...
}
You could also keep the instance of RepositoryFactory instead of already getting the Repository instance.
I hope this can be useful to someone.
Beyond what Kohányi has said, you could load the DAO or entity classes reflectively by name, and then bind only the specific types asked for in the command-line arguments:
package com.example;
public class App
{
public static void main(final String[] args)
{
final Injector appleInjector = Guice.createInjector(new DynamicDaoModule(getClass("com.example.AppleDao")));
appleInjector.getInstance(Runner.class);
final Injector orangeInjector = Guice.createInjector(new DynamicDaoModule( getClass("com.example.OrangeDao")));
orangeInjector.getInstance(Runner.class);
// final Injector commandLineInjector = Guice.createInjector(new DynamicDaoModule(getClass(args[0])));
// commandLineInjector.getInstance(Runner.class);
}
private static Class getClass(final String className)
{
try
{
return Class.forName(className);
}
catch (final ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
}
class DynamicDaoModule extends AbstractModule
{
private final Class<? extends GenericDao<? extends Entity>> daoClass;
public DynamicDaoModule(final Class<? extends GenericDao<? extends Entity>> daoClass)
{
this.daoClass = daoClass;
}
#Override
protected void configure()
{
// bind GenericDao<? extends Entity> to daoClass
final TypeLiteral<GenericDao<? extends Entity>> daoOfEntity = (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(GenericDao.class, Types.subtypeOf(Entity.class)));
bind(daoOfEntity).to(daoClass);
}
}
interface Entity
{
}
class Apple implements Entity
{
}
class Orange implements Entity
{
}
class Runner
{
#Inject
public Runner(final GenericDao<? extends Entity> dao)
{
System.out.println("This runner has an " + dao);
}
}
class GenericDao<T extends Entity>
{
private final Class<? extends Entity> entityClass;
protected GenericDao(final Class<? extends Entity> entityClass)
{
this.entityClass = entityClass;
}
#Override
public String toString()
{
return String.format("%s constructed with entityClass %s", getClass().getSimpleName(), entityClass.getSimpleName());
}
}
class AppleDao extends GenericDao<Apple>
{
#Inject
public AppleDao()
{
super(Apple.class);
}
}
class OrangeDao extends GenericDao<Orange>
{
#Inject
public OrangeDao()
{
super(Orange.class);
}
}
And the output would be
This runner has an AppleDao constructed with entityClass Apple
This runner has an OrangeDao constructed with entityClass Orange
I have changed the example to have entity classes implement an interface, in case they share some functionality that would be useful to Runner or GenericDao. If in fact you don't have such an interface, the technique also works with entity classes like String and Double if you remove the extends Entity upper bounds (e.g. GenericDao<T>).
I also removed the <T> parameter on Runner, as that was providing no benefit due to type erasure. If you were to subclass Runner<T>, then you might have Guice provide AppleRunner extends Runner<Apple> or OrangeRunner extends Runner<Orange>. But the type parameter provides nothing if Runner itself is the only concrete class Guice will be providing.
EDIT Oops, I left the class injections in. They are removed now. Of course, if you have a concrete GenericDao subclass for each entity, then perhaps you don't need to inject the entity classes themselves.
I suppose it's not clear to me whether you can provide concrete GenericDao subclasses for all the entity types ahead of time or not. If not, and you were only using the GenericDao class itself for each different kind of entity class, then you would want to inject concrete entity classes and not concrete DAO classes.

Categories

Resources