Gwt请求工厂。客户端的泛型和继承

时间:2015-11-26 14:53:08

标签: generics inheritance gwt polymorphism requestfactory

我正在尝试编写泛型类以避免代码重复。 我想有通用的方法:

  1. 通过id从服务器获取实体/模型。
  2. 从服务器获取所有实体/模型的列表。
  3. 发送到服务器并保存在数据库实体/模型中。
  4. 它应该与Generic类一起使用,例如:

    Services<PizzaProxy> factory = GWT.create(Services.class);
    factory.initialize(new SimpleEventBus());
    GenericContext<PizzaProxy> context = factory.genericContext();
    context.get().to(new Receiver<List<GenericProxy<PizzaProxy>>>() {
        @Override
        public void onSuccess(List<GenericProxy<PizzaProxy>> response) {
            for(GenericProxy<PizzaProxy> p: response) {
                logger.severe(p.getId()) + " " + p.getVersion());
            }
        }
    }).fire();
    

    我有服务器端。现在我在使用客户端代码。

    目标是写:

    • GenericModel
    • GenericDao
    • GenericLocator
    • GenericService
    • GenericProxy
    • GenericContext

    这是我的服务器端代码,它可以工作(不会报告任何编译或运行时错误,正如我想的那样):

    服务器

    GenericModel

    @MappedSuperclass
    public  class GenericModel<T extends GenericModel<T>> implements Identifiable, Versionable {
        @Transient
        protected Class<T> entityClass;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Version
        private Integer version;
    
        // setter & getter
        @Override
        public Long getId() {return id;}
        public void setId(Long id) {this.id = id;}
        @Override
        public Integer getVersion() {return version;}
        public void setVersion(Integer version) {this.version = version;}
    
        // constructor
        public GenericModel() {
            Class<?> obtainedClass = getClass();
            Type genericSuperclass = null;
            for (;;) {
                genericSuperclass = obtainedClass.getGenericSuperclass();
                if (genericSuperclass instanceof ParameterizedType) {
                    break;
                }
                obtainedClass = obtainedClass.getSuperclass();
            }
            ParameterizedType genericSuperclass_ = (ParameterizedType) genericSuperclass;
            try {
                entityClass = ((Class) ((Class) genericSuperclass_
                        .getActualTypeArguments()[0]));
            } catch (ClassCastException e) {
                entityClass = guessEntityClassFromTypeParametersClassTypedArgument();
            }
            }
    }
    

    GenericDao

    public class GenericDao<T extends GenericModel<T>> {
        @Transient protected Class<T> entityClass;
    
        public GenericDao(Class<? extends GenericModel<T>> clazz) {
            this.entityClass = (Class<T>) clazz;
        }
    
        public T getBy(Long id) {
            return JPA.em().find(entityClass, id);
        }
        public List<T> get() {
            return getList();
        }
        public List<T> getList() {
            return (List<T>) JPA.em().createQuery("FROM " + entityClass.getSimpleName()).getResultList();
        }
    
    
        public void save(T entityClass) {
            JPA.em().persist(entityClass);
        }
        public T saveAndReturn(T entityClass) {
            this.save(entityClass);
            return entityClass;
        }
    
        public void saveOrUpdate(T entityClass) {
            // TODO
        }
    
        public void update(T genericDao) {
            JPA.em().merge(genericDao);
        }
    
        public void delete(T genericDao) {
            JPA.em().remove(genericDao);
        }
    
    
        @PrePersist
        protected void prePersist() {
            preUpdate();
        }
        @PreUpdate
        protected void preUpdate() {
            // TODO Update Version
        }
    
    }
    

    GenericLocator

    public class GenericLocator<GL extends GenericLocator<GL, GD, GM, id>, GD extends GenericDao<GM>, GM extends GenericModel<GM>, id> extends Locator<GenericModel<GM>, Long> {
    
        @Override
        public GenericModel<GM> create(Class<? extends GenericModel<GM>> clazz) {
            try {
                return clazz.newInstance();
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public GenericModel<GM> find(Class<? extends GenericModel<GM>> clazz, Long id) {
            GenericDao<GM> dao = new GenericDao<GM>(clazz);
            return dao.getBy(id);
        }
    
    
        @Override
        public Class<GenericModel<GM>> getDomainType() {
            GenericModel<GM> model = new GenericModel<GM>();
            return (Class<GenericModel<GM>>) model.getClass();
        }
        @Override
        public Long getId(GenericModel<GM> model) {
            return model.getId();
        }
        @Override
        public Integer getVersion(GenericModel<GM> model) {
            return model.getVersion();
        }
        @Override
        public Class<Long> getIdType() {
            return Long.class;
        }
    }
    

    客户端/ SHARED

    GenericProxy

    @ProxyFor(value = GenericModel.class, locator = GenericLocator.class)
    public interface GenericProxy<T extends GenericProxy<T>> extends EntityProxy {
        public Long getId();
        public Integer getVersion();
    }
    

    GenericContext

    @Service(value = GenericDao.class, locator = MyServiceLocator.class)
    public interface GenericContext<T extends GenericProxy<T>> extends RequestContext {
        Request<T> getBy(Long id);
        Request<List<T>> get();
        Request<Void> save(T entity);
    }
    

    以下是发生的编译错误:

    [INFO]    Adding '2' new generated units
    [INFO]       See snapshot: /tmp/pl.derp.shared.rf.GenericContextImpl5428453302732754803.java
    [INFO]       Ignored 1 unit with compilation errors in first pass.
    [INFO] Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
    [INFO]    Tracing compile failure path for type 'pl.derp.shared.rf.GenericContextImpl'
    [INFO]       [ERROR] Errors in '/home/korbeldaniel/git/derp3/tutorial/target/.generated/pl/derp/shared/rf/GenericContextImpl.java'
    [INFO]          [ERROR] Line 22: T cannot be resolved to a type
    [INFO]          [ERROR] Line 29: T cannot be resolved to a type
    [INFO]          [ERROR] Line 18: The interface Request cannot be implemented more than once with different arguments: Request<List<T>> and Request<List<T>>
    [INFO]          [ERROR] Line 22: T cannot be resolved to a variable
    [INFO]          [ERROR] Line 22: Syntax error on token "extends", instanceof expected
    [INFO]          [ERROR] Line 30: The interface Request cannot be implemented more than once with different arguments: Request<T> and Request<T>
    [INFO]          [ERROR] Line 41: T cannot be resolved to a type
    [INFO]          [ERROR] Line 17: T cannot be resolved to a type
    [INFO]          [ERROR] Line 30: T cannot be resolved to a type
    [INFO]          [ERROR] Line 22: Syntax error on token "class", invalid Name
    [INFO]          [ERROR] Line 20: The method with(String...) from the type AbstractRequest<BaseProxy,List<T>> refers to the missing type T
    [INFO]          [ERROR] Line 3: The type GenericContextImpl must implement the inherited abstract method GenericContext.save(GenericProxy)
    [INFO]          [ERROR] Line 32: The method with(String...) from the type AbstractRequest<BaseProxy,T> refers to the missing type T
    [INFO]          [ERROR] Line 18: T cannot be resolved to a type
    [INFO]    [ERROR] Hint: Check that the type name 'pl.derp.shared.rf.GenericContextImpl' is really what you meant
    [INFO]    [ERROR] Hint: Check that your classpath includes all required source roots
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    

    正如您所看到的,错误指向了我的请求工厂接口的生成类实现。我不知道如何处理它。

0 个答案:

没有答案