001: /*
002: * Created on 08-Jan-2006
003: */
004: package uk.org.ponder.rsf.hibernate3;
005:
006: import java.util.ArrayList;
007: import java.util.HashMap;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.Map;
011:
012: import org.hibernate.Query;
013: import org.hibernate.Session;
014: import org.springframework.beans.factory.FactoryBean;
015:
016: import uk.org.ponder.beanutil.BeanLocator;
017: import uk.org.ponder.beanutil.WriteableBeanLocator;
018: import uk.org.ponder.util.UniversalRuntimeException;
019:
020: /**
021: * A request-scope query bean that will return a list of objects in response to
022: * an HQL query string. This bean is bi-modal - when used as a WBL it will
023: * curry successive path components into successive named parameters
024: * of the query. When used as a plain FactoryBean, it will expect the
025: * path components to have been configured into it as dependencies.
026: *
027: * Use this bean only in one mode at once per instance!
028: *
029: * @author Antranig Basman (antranig@caret.cam.ac.uk)
030: */
031: // TODO: "curried" mode will currently not work due to strange structure in
032: // MethodAnalyser wrapping.
033: public class HQLParameterQueryBean implements WriteableBeanLocator,
034: FactoryBean {
035: private Session session;
036: private String hqlstring;
037: private Query query;
038: private String[] paramnames;
039: private Map paramcache = new HashMap();
040:
041: // Key - param vals, value, query results
042: private Map querycache = new HashMap();
043: // The cache for use as a FactoryBean
044: private List cached;
045:
046: public void setSession(Session session) {
047: this .session = session;
048: }
049:
050: public void setHQLString(String hqlstring) {
051: this .hqlstring = hqlstring;
052: }
053:
054: private Query createQuery(String hqlstring) {
055: return session.createQuery(hqlstring);
056: }
057:
058: public void init() {
059: query = createQuery(hqlstring);
060: for (Iterator pit = paramcache.keySet().iterator(); pit
061: .hasNext();) {
062: String key = (String) pit.next();
063: Object value = paramcache.get(key);
064: query.setParameter(key, value);
065: }
066: }
067:
068: private class ParameterRover implements BeanLocator {
069: private List paramvals;
070:
071: public ParameterRover() {
072: }
073:
074: public ParameterRover(List sofar, String path) {
075: paramvals = new ArrayList(sofar);
076: paramvals.addAll(sofar);
077: paramvals.add(path);
078: }
079:
080: public Object locateBean(String path) {
081: if (paramvals.size() == paramnames.length) {
082: Object cached = querycache.get(paramvals);
083: if (cached != null) {
084: return cached;
085: }
086: List results = null;
087: try {
088: Query doquery = createQuery(hqlstring);
089:
090: for (int i = 0; i < paramnames.length; ++i) {
091: doquery.setParameter(i, paramvals.get(i));
092: }
093: results = query.list();
094: } catch (Exception e) {
095: throw UniversalRuntimeException.accumulate(e,
096: "Error performing Hibernate query");
097: }
098: querycache.put(paramvals, results);
099: return results;
100: } else
101: return new ParameterRover(paramvals, path);
102: }
103:
104: }
105:
106: public Object locateBean(String path) {
107: return new ParameterRover().locateBean(path);
108: }
109:
110: public Object getObject() throws Exception {
111: if (cached == null) {
112: cached = query.list();
113: }
114: return cached;
115: }
116:
117: public Class getObjectType() {
118: return List.class;
119: }
120:
121: public boolean isSingleton() {
122: return true;
123: }
124:
125: public boolean remove(String beanname) {
126: throw new UnsupportedOperationException(
127: "Cannot \"remove\" from HQLParameterQueryBean");
128: }
129:
130: public void set(String beanname, Object toset) {
131: paramcache.put(beanname, toset);
132: }
133:
134: }
|