Pabrik Permintaan Gwt. Generik dan Warisan di sisi klien

Saya mencoba menulis kelas generik untuk menghindari pengulangan kode. Saya ingin memiliki metode umum untuk:

  1. Dapatkan Entitas/Model dari server berdasarkan id.
  2. Dapatkan Daftar semua Entitas/Model dari server.
  3. Kirim ke server dan simpan di db Entity/Model.

Ini harus bekerja dengan kelas Generik, misalnya:

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();

Saya memiliki sisi server yang berfungsi. Sekarang saya kesulitan dengan kode sisi klien.

Tujuannya adalah untuk menulis:

  • GenericModel,
  • GenericDao,
  • GenericLocator,
  • GenericService,
  • GenericProxy,
  • GenericContext.

Ini adalah kode sisi server saya, yang berfungsi (tidak melaporkan kesalahan kompilasi atau run-time apa pun, seperti yang saya kira):

SERVER

Model Generik

@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();
        }
        }
}

GenerikDao

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
    }

}

Pencari Generik

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;
    }
}

KLIEN/DIBAGIKAN

Proksi Generik

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

Konteks Generik

@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);
}

Berikut kesalahan kompilasi yang terjadi:

[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

Seperti yang Anda lihat, kesalahan mengarah ke implementasi kelas yang dihasilkan dari antarmuka pabrik permintaan saya. Saya tidak tahu bagaimana menghadapinya.


person masterdany88    schedule 26.11.2015    source sumber
comment
Tidak jelas. Pekerjaan apa ? Apa yang tidak? Atau apakah Anda mencari review kode. Silakan edit pertanyaan atau kiriman ke codereview.stackexchange.com   -  person kebs    schedule 26.11.2015