2010年4月15日木曜日

JDO の Query を Generics に対応させてみた。

javax.jdo.Query interface の execute() メソッドは戻り値が java.lang.Object 型なので、以下のようにキャストする必要があります。

Collection<User> users = (Collection<User>)query.execute();

でも、めんどくさいです。(´・ω・`)

しかも、キャストのところでコンパイラが警告を出します。

@SuppressWarning("unchecked") とか書けば警告は消えますが。

でも、めんどくさいです。(´・ω・`)

ということで、execute系メソッドの引数として型変数を渡せるようなクラスを作成してみました。

PersistenceManagerExt.java
package com.objectfanatics.gae.datastore;

import java.util.Collection;
import java.util.Date;
import java.util.EnumSet;
import java.util.Set;

import javax.jdo.Extent;
import javax.jdo.FetchGroup;
import javax.jdo.FetchPlan;
import javax.jdo.JDOException;
import javax.jdo.ObjectState;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Transaction;
import javax.jdo.datastore.JDOConnection;
import javax.jdo.datastore.Sequence;
import javax.jdo.listener.InstanceLifecycleListener;

/**
 * PersistenceManager for QueryExt.
 */
public class PersistenceManagerExt implements PersistenceManager {
 
 /**
  * PersistenceManager instance to be delegated.
  */
 private final PersistenceManager instance;
 
 /**
  * Constructor.
  * 
  * @param instance instance to be delegated
  */
 public PersistenceManagerExt(PersistenceManager instance) {
  this.instance = instance;
 }
 
 // for generics
 @SuppressWarnings("unchecked")
 @Override
 public QueryExt newNamedQuery(Class cls, String filter) {
  return new QueryExt(instance.newNamedQuery(cls, filter));
 }
 @Override
 public QueryExt newQuery() {
  return new QueryExt(instance.newQuery());
 }
 @SuppressWarnings("unchecked")
 @Override
 public QueryExt newQuery(Class cls, Collection cln, String filter) {
  return new QueryExt(instance.newQuery(cls, cln, filter));
 }
 @SuppressWarnings("unchecked")
 @Override
 public QueryExt newQuery(Class cls, Collection cln) {
  return new QueryExt(instance.newQuery(cls, cln));
 }
 @SuppressWarnings("unchecked")
 @Override
 public QueryExt newQuery(Class cls, String filter) {
  return new QueryExt(instance.newQuery(cls, filter));
 }
 @SuppressWarnings("unchecked")
 @Override
 public QueryExt newQuery(Class cls) {
  return new QueryExt(instance.newQuery(cls));
 }
 @SuppressWarnings("unchecked")
 @Override
 public QueryExt newQuery(Extent cln, String filter) {
  return new QueryExt(instance.newQuery(cln, filter));
 }
 @SuppressWarnings("unchecked")
 @Override
 public QueryExt newQuery(Extent cln) {
  return new QueryExt(instance.newQuery(cln));
 }
 @Override
 public QueryExt newQuery(Object compiled) {
  return new QueryExt(instance.newQuery(compiled));
 }
 @Override
 public QueryExt newQuery(String language, Object query) {
  return new QueryExt(instance.newQuery(language, query));
 }
 @Override
 public QueryExt newQuery(String query) {
  return new QueryExt(instance.newQuery(query));
 }
 
 // delegate methods.
 @SuppressWarnings("unchecked")
 @Override
 public void addInstanceLifecycleListener(InstanceLifecycleListener listener, Class... classes) {
  instance.addInstanceLifecycleListener(listener, classes);
 }
 @Override
 public void checkConsistency() {
  instance.checkConsistency();
 }
 @Override
 public void close() {
  instance.close();
 }
 @Override
 public Transaction currentTransaction() {
  return instance.currentTransaction();
 }
 @Override
 public void deletePersistent(Object pc) {
  instance.deletePersistent(pc);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void deletePersistentAll(Collection pcs) {
  instance.deletePersistentAll(pcs);
 }
 @Override
 public void deletePersistentAll(Object... pcs) {
  instance.deletePersistentAll(pcs);
 }
 @Override
 public <T> T detachCopy(T pc) {
  return instance.detachCopy(pc);
 }
 @Override
 public <T> Collection<T> detachCopyAll(Collection<T> pcs) {
  return instance.detachCopyAll(pcs);
 }
 @Override
 public <T> T[] detachCopyAll(T... pcs) {
  return instance.detachCopyAll(pcs);
 }
 @Override
 public void evict(Object pc) {
  instance.evict(pc);
 }
 @Override
 public void evictAll() {
  instance.evictAll();
 }
 @SuppressWarnings("unchecked")
 @Override
 public void evictAll(boolean subclasses, Class pcClass) {
  instance.evictAll(subclasses, pcClass);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void evictAll(Collection pcs) {
  instance.evictAll(pcs);
 }
 @Override
 public void evictAll(Object... pcs) {
  instance.evictAll(pcs);
 }
 @Override
 public void flush() {
  instance.flush();
 }
 @Override
 public boolean getCopyOnAttach() {
  return instance.getCopyOnAttach();
 }
 @Override
 public JDOConnection getDataStoreConnection() {
  return instance.getDataStoreConnection();
 }
 @Override
 public boolean getDetachAllOnCommit() {
  return instance.getDetachAllOnCommit();
 }
 @Override
 public <T> Extent<T> getExtent(Class<T> persistenceCapableClass, boolean subclasses) {
  return instance.getExtent(persistenceCapableClass, subclasses);
 }
 @Override
 public <T> Extent<T> getExtent(Class<T> persistenceCapableClass) {
  return instance.getExtent(persistenceCapableClass);
 }
 @SuppressWarnings("unchecked")
 @Override
 public FetchGroup getFetchGroup(Class cls, String name) {
  return instance.getFetchGroup(cls, name);
 }
 @Override
 public FetchPlan getFetchPlan() {
  return instance.getFetchPlan();
 }
 @Override
 public boolean getIgnoreCache() {
  return instance.getIgnoreCache();
 }
 @SuppressWarnings("unchecked")
 @Override
 public Set getManagedObjects() {
  return instance.getManagedObjects();
 }
 @SuppressWarnings("unchecked")
 @Override
 public Set getManagedObjects(Class... classes) {
  return instance.getManagedObjects(classes);
 }
 @SuppressWarnings("unchecked")
 @Override
 public Set getManagedObjects(EnumSet<ObjectState> states, Class... classes) {
  return instance.getManagedObjects(states, classes);
 }
 @SuppressWarnings("unchecked")
 @Override
 public Set getManagedObjects(EnumSet<ObjectState> states) {
  return instance.getManagedObjects(states);
 }
 @Override
 public boolean getMultithreaded() {
  return instance.getMultithreaded();
 }
 @Override
 public <T> T getObjectById(Class<T> cls, Object key) {
  return instance.getObjectById(cls, key);
 }
 @Override
 public Object getObjectById(Object oid, boolean validate) {
  return instance.getObjectById(oid, validate);
 }
 @Override
 public Object getObjectById(Object oid) {
  return instance.getObjectById(oid);
 }
 @Override
 public Object getObjectId(Object pc) {
  return instance.getObjectId(pc);
 }
 @SuppressWarnings("unchecked")
 @Override
 public Class getObjectIdClass(Class cls) {
  return instance.getObjectIdClass(cls);
 }
 @Override
 public Object[] getObjectsById(boolean validate, Object... oids) {
  return instance.getObjectsById(validate, oids);
 }
 @SuppressWarnings("unchecked")
 @Override
 public Collection getObjectsById(Collection oids, boolean validate) {
  return instance.getObjectsById(oids, validate);
 }
 @SuppressWarnings("unchecked")
 @Override
 public Collection getObjectsById(Collection oids) {
  return instance.getObjectsById(oids);
 }
 @Override
 public Object[] getObjectsById(Object... oids) {
  return instance.getObjectsById(oids);
 }
 @SuppressWarnings("deprecation")
 @Override
 public Object[] getObjectsById(Object[] oids, boolean validate) {
  return instance.getObjectsById(oids, validate);
 }
 @Override
 public PersistenceManagerFactory getPersistenceManagerFactory() {
  return instance.getPersistenceManagerFactory();
 }
 @Override
 public Integer getQueryTimeoutMillis() {
  return instance.getQueryTimeoutMillis();
 }
 @Override
 public Sequence getSequence(String name) {
  return instance.getSequence(name);
 }
 @Override
 public Date getServerDate() {
  return instance.getServerDate();
 }
 @Override
 public Object getTransactionalObjectId(Object pc) {
  return instance.getTransactionalObjectId(pc);
 }
 @Override
 public Object getUserObject() {
  return instance.getUserObject();
 }
 @Override
 public Object getUserObject(Object key) {
  return instance.getUserObject(key);
 }
 @Override
 public boolean isClosed() {
  return instance.isClosed();
 }
 @Override
 public void makeNontransactional(Object pc) {
  instance.makeNontransactional(pc);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void makeNontransactionalAll(Collection pcs) {
  instance.makeNontransactionalAll(pcs);
 }
 @Override
 public void makeNontransactionalAll(Object... pcs) {
  instance.makeNontransactionalAll(pcs);
 }
 @Override
 public <T> T makePersistent(T pc) {
  return instance.makePersistent(pc);
 }
 @Override
 public <T> Collection<T> makePersistentAll(Collection<T> pcs) {
  return instance.makePersistentAll(pcs);
 }
 @Override
 public <T> T[] makePersistentAll(T... pcs) {
  return instance.makePersistentAll(pcs);
 }
 @Override
 public void makeTransactional(Object pc) {
  instance.makeTransactional(pc);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void makeTransactionalAll(Collection pcs) {
  instance.makeTransactionalAll(pcs);
 }
 @Override
 public void makeTransactionalAll(Object... pcs) {
  instance.makeTransactionalAll(pcs);
 }
 @Override
 public void makeTransient(Object pc, boolean useFetchPlan) {
  instance.makeTransient(pc, useFetchPlan);
 }
 @Override
 public void makeTransient(Object pc) {
  instance.makeTransient(pc);
 }
 @Override
 public void makeTransientAll(boolean useFetchPlan, Object... pcs) {
  instance.makeTransientAll(useFetchPlan, pcs);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void makeTransientAll(Collection pcs, boolean useFetchPlan) {
  instance.makeTransientAll(pcs, useFetchPlan);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void makeTransientAll(Collection pcs) {
  instance.makeTransientAll(pcs);
 }
 @Override
 public void makeTransientAll(Object... pcs) {
  instance.makeTransientAll(pcs);
 }
 @SuppressWarnings("deprecation")
 @Override
 public void makeTransientAll(Object[] pcs, boolean useFetchPlan) {
  instance.makeTransientAll(pcs, useFetchPlan);
 }
 @Override
 public <T> T newInstance(Class<T> pcClass) {
  return instance.newInstance(pcClass);
 }
 @SuppressWarnings("unchecked")
 @Override
 public Object newObjectIdInstance(Class pcClass, Object key) {
  return instance.newObjectIdInstance(pcClass, key);
 }
 @Override
 public Object putUserObject(Object key, Object val) {
  return instance.putUserObject(key, val);
 }
 @Override
 public void refresh(Object pc) {
  instance.refresh(pc);
 }
 @Override
 public void refreshAll() {
  instance.refreshAll();
 }
 @SuppressWarnings("unchecked")
 @Override
 public void refreshAll(Collection pcs) {
  instance.refreshAll(pcs);
 }
 @Override
 public void refreshAll(JDOException jdoe) {
  instance.refreshAll(jdoe);
 }
 @Override
 public void refreshAll(Object... pcs) {
  instance.refreshAll(pcs);
 }
 @Override
 public void removeInstanceLifecycleListener(InstanceLifecycleListener listener) {
  instance.removeInstanceLifecycleListener(listener);
 }
 @Override
 public Object removeUserObject(Object key) {
  return instance.removeUserObject(key);
 }
 @Override
 public void retrieve(Object pc, boolean useFetchPlan) {
  instance.retrieve(pc, useFetchPlan);
 }
 @Override
 public void retrieve(Object pc) {
  instance.retrieve(pc);
 }
 @Override
 public void retrieveAll(boolean useFetchPlan, Object... pcs) {
  instance.retrieveAll(useFetchPlan, pcs);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void retrieveAll(Collection pcs, boolean useFetchPlan) {
  instance.retrieveAll(pcs, useFetchPlan);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void retrieveAll(Collection pcs) {
  instance.retrieveAll(pcs);
 }
 @Override
 public void retrieveAll(Object... pcs) {
  instance.retrieveAll(pcs);
 }
 @SuppressWarnings("deprecation")
 @Override
 public void retrieveAll(Object[] pcs, boolean useFetchPlan) {
  instance.retrieveAll(pcs, useFetchPlan);
 }
 @Override
 public void setCopyOnAttach(boolean flag) {
  instance.setCopyOnAttach(flag);
 }
 @Override
 public void setDetachAllOnCommit(boolean flag) {
  instance.setDetachAllOnCommit(flag);
 }
 @Override
 public void setIgnoreCache(boolean flag) {
  instance.setIgnoreCache(flag);
 }
 @Override
 public void setMultithreaded(boolean flag) {
  instance.setMultithreaded(flag);
 }
 @Override
 public void setQueryTimeoutMillis(Integer interval) {
  instance.setQueryTimeoutMillis(interval);
 }
 @Override
 public void setUserObject(Object o) {
  instance.setUserObject(o);
 }
}


QueryExt.java
package com.objectfanatics.gae.datastore;

import java.util.Collection;
import java.util.Map;

import javax.jdo.Extent;
import javax.jdo.FetchPlan;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;

/**
 * Generics enabled Query extension.
 */
public class QueryExt implements Query {
 
 /**
  * Query instance to be delegated.
  */
 private final Query instanceToBeDelegated;
 
 /**
  * Constructor.
  * @param instanceToBeDelegated Query instance to be delegated
  */
 public QueryExt(Query instanceToBeDelegated) {
  if (instanceToBeDelegated == null) throw new IllegalArgumentException("instanceToBeDelegated must not be null.");
  this.instanceToBeDelegated = instanceToBeDelegated;
 }
 
 // for generics.
 @SuppressWarnings("unchecked")
 public <T> Collection<T> executeExt(Class<T> t) {
  return (Collection<T>)instanceToBeDelegated.execute();
 }
 @SuppressWarnings("unchecked")
 public <T> Collection<T> executeExt(Class<T> t, Object p1, Object p2, Object p3) {
  return (Collection<T>)instanceToBeDelegated.execute(p1, p2, p3);
 }
 @SuppressWarnings("unchecked")
 public <T> Collection<T> executeExt(Class<T> t, Object p1, Object p2) {
  return (Collection<T>)instanceToBeDelegated.execute(p1, p2);
 }
 @SuppressWarnings("unchecked")
 public <T> Collection<T> executeExt(Class<T> t, Object p1) {
  return (Collection<T>)instanceToBeDelegated.execute(p1);
 }
 @SuppressWarnings("unchecked")
 public <T> Collection<T> executeWithArrayExt(Class<T> t, Object... parameters) {
  return (Collection<T>)instanceToBeDelegated.executeWithArray(parameters);
 }
 @SuppressWarnings("unchecked")
 public <T> Collection<T> executeWithMapExt(Class<T> t, Map parameters) {
  return (Collection<T>)instanceToBeDelegated.executeWithMap(parameters);
 }
 
 // delegate methods.
 @Override
 public void addExtension(String key, Object value) {
  instanceToBeDelegated.addExtension(key, value);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void addSubquery(Query sub, String variableDeclaration, String candidateCollectionExpression, Map parameters) {
  instanceToBeDelegated.addSubquery(sub, variableDeclaration, candidateCollectionExpression, parameters);
 }
 @Override
 public void addSubquery(Query sub, String variableDeclaration, String candidateCollectionExpression, String... parameters) {
  instanceToBeDelegated.addSubquery(sub, variableDeclaration, candidateCollectionExpression, parameters);
 }
 @Override
 public void addSubquery(Query sub, String variableDeclaration, String candidateCollectionExpression, String parameter) {
  instanceToBeDelegated.addSubquery(sub, variableDeclaration, candidateCollectionExpression, parameter);
 }
 @Override
 public void addSubquery(Query sub, String variableDeclaration, String candidateCollectionExpression) {
  instanceToBeDelegated.addSubquery(sub, variableDeclaration, candidateCollectionExpression);
 }
 @Override
 public void cancel(Thread thread) {
  instanceToBeDelegated.cancel(thread);
 }
 @Override
 public void cancelAll() {
  instanceToBeDelegated.cancelAll();
 }
 @Override
 public void close(Object queryResult) {
  instanceToBeDelegated.close(queryResult);
 }
 @Override
 public void closeAll() {
  instanceToBeDelegated.closeAll();
 }
 @Override
 public void compile() {
  instanceToBeDelegated.compile();
 }
 @Override
 public void declareImports(String imports) {
  instanceToBeDelegated.declareImports(imports);
 }
 @Override
 public void declareParameters(String parameters) {
  instanceToBeDelegated.declareParameters(parameters);
 }
 @Override
 public void declareVariables(String variables) {
  instanceToBeDelegated.declareVariables(variables);
 }
 @Override
 public long deletePersistentAll() {
  return instanceToBeDelegated.deletePersistentAll();
 }
 @SuppressWarnings("unchecked")
 @Override
 public long deletePersistentAll(Map parameters) {
  return instanceToBeDelegated.deletePersistentAll(parameters);
 }
 @Override
 public long deletePersistentAll(Object... parameters) {
  return instanceToBeDelegated.deletePersistentAll(parameters);
 }
 @Override
 public Object execute() {
  return instanceToBeDelegated.execute();
 }
 @Override
 public Object execute(Object p1, Object p2, Object p3) {
  return instanceToBeDelegated.execute(p1, p2, p3);
 }
 @Override
 public Object execute(Object p1, Object p2) {
  return instanceToBeDelegated.execute(p1, p2);
 }
 @Override
 public Object execute(Object p1) {
  return instanceToBeDelegated.execute(p1);
 }
 @Override
 public Object executeWithArray(Object... parameters) {
  return instanceToBeDelegated.executeWithArray(parameters);
 }
 @SuppressWarnings("unchecked")
 @Override
 public Object executeWithMap(Map parameters) {
  return instanceToBeDelegated.executeWithMap(parameters);
 }
 @Override
 public FetchPlan getFetchPlan() {
  return instanceToBeDelegated.getFetchPlan();
 }
 @Override
 public boolean getIgnoreCache() {
  return instanceToBeDelegated.getIgnoreCache();
 }
 @Override
 public PersistenceManager getPersistenceManager() {
  return instanceToBeDelegated.getPersistenceManager();
 }
 @Override
 public Boolean getSerializeRead() {
  return instanceToBeDelegated.getSerializeRead();
 }
 @Override
 public Integer getTimeoutMillis() {
  return instanceToBeDelegated.getTimeoutMillis();
 }
 @Override
 public boolean isUnmodifiable() {
  return instanceToBeDelegated.isUnmodifiable();
 }
 @SuppressWarnings("unchecked")
 @Override
 public void setCandidates(Collection pcs) {
  instanceToBeDelegated.setCandidates(pcs);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void setCandidates(Extent pcs) {
  instanceToBeDelegated.setCandidates(pcs);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void setClass(Class cls) {
  instanceToBeDelegated.setClass(cls);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void setExtensions(Map extensions) {
  instanceToBeDelegated.setExtensions(extensions);
 }
 @Override
 public void setFilter(String filter) {
  instanceToBeDelegated.setFilter(filter);
 }
 @Override
 public void setGrouping(String group) {
  instanceToBeDelegated.setGrouping(group);
 }
 @Override
 public void setIgnoreCache(boolean ignoreCache) {
  instanceToBeDelegated.setIgnoreCache(ignoreCache);
 }
 @Override
 public void setOrdering(String ordering) {
  instanceToBeDelegated.setOrdering(ordering);
 }
 @Override
 public void setRange(long fromIncl, long toExcl) {
  instanceToBeDelegated.setRange(fromIncl, toExcl);
 }
 @Override
 public void setRange(String fromInclToExcl) {
  instanceToBeDelegated.setRange(fromInclToExcl);
 }
 @Override
 public void setResult(String data) {
  instanceToBeDelegated.setResult(data);
 }
 @SuppressWarnings("unchecked")
 @Override
 public void setResultClass(Class cls) {
  instanceToBeDelegated.setResultClass(cls);
 }
 @Override
 public void setSerializeRead(Boolean serialize) {
  instanceToBeDelegated.setSerializeRead(serialize);
 }
 @Override
 public void setTimeoutMillis(Integer interval) {
  instanceToBeDelegated.setTimeoutMillis(interval);
 }
 @Override
 public void setUnique(boolean unique) {
  instanceToBeDelegated.setUnique(unique);
 }
 @Override
 public void setUnmodifiable() {
  instanceToBeDelegated.setUnmodifiable();
 }
}

PersistenceManager のいくつかの newQuery() 系のメソッドは引数でエンティティの型を受け取っているので、それを利用すれば QueryExt<T> のような形でエンティティの型を渡すこともできそうですね。要検討ということで。

0 件のコメント:

コメントを投稿