001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com> and
003: * JR Boyens <gnu-jrb[remove] at gmx dot net>
004: * Distributed under the terms of either:
005: * - the common development and distribution license (CDDL), v1.0; or
006: * - the GNU Lesser General Public License, v2.1 or later
007: * $Id: GenericQueryManagerFactory.java 3634 2007-01-08 21:42:24Z gbevin $
008: */
009: package com.uwyn.rife.database.querymanagers.generic;
010:
011: import com.uwyn.rife.database.Datasource;
012: import com.uwyn.rife.database.DbQueryManagerCache;
013: import com.uwyn.rife.database.exceptions.DatabaseException;
014: import com.uwyn.rife.database.exceptions.UnsupportedJdbcDriverException;
015: import com.uwyn.rife.database.querymanagers.generic.exceptions.MissingDefaultConstructorException;
016: import com.uwyn.rife.site.Constrained;
017: import com.uwyn.rife.site.ConstrainedProperty;
018: import com.uwyn.rife.site.ConstrainedUtils;
019: import com.uwyn.rife.tools.ClassUtils;
020: import com.uwyn.rife.tools.StringUtils;
021: import java.lang.reflect.Constructor;
022: import java.lang.reflect.InvocationTargetException;
023: import java.util.Collection;
024:
025: public class GenericQueryManagerFactory {
026: private final static String GENERIC_DRIVER = "generic";
027:
028: private static DbQueryManagerCache mCache = new DbQueryManagerCache();
029: private static String mPackageName = GenericQueryManagerFactory.class
030: .getPackage().getName()
031: + ".databasedrivers.";
032:
033: public static <BeanType> GenericQueryManager<BeanType> getInstance(
034: Datasource datasource, Class<BeanType> beanClass)
035: throws DatabaseException {
036: String short_name = ClassUtils.shortenClassName(beanClass);
037:
038: return getInstance(datasource, beanClass, short_name);
039: }
040:
041: public static <BeanType> GenericQueryManager<BeanType> getInstance(
042: Datasource datasource, Class<BeanType> beanClass,
043: String tableName) throws DatabaseException {
044: AbstractGenericQueryManager<BeanType> query_manager = null;
045:
046: String driver = datasource.getAliasedDriver();
047:
048: try {
049: beanClass.getConstructor(new Class[] {});
050: } catch (NoSuchMethodException e) {
051: throw new MissingDefaultConstructorException(beanClass, e);
052: }
053:
054: // get the identifier column
055: String primary_key = null;
056:
057: boolean has_identifier = false;
058: Constrained constrained_bean = ConstrainedUtils
059: .getConstrainedInstance(beanClass);
060: if (constrained_bean != null) {
061: for (ConstrainedProperty property : (Collection<ConstrainedProperty>) constrained_bean
062: .getConstrainedProperties()) {
063: if (property.isIdentifier()) {
064: primary_key = property.getPropertyName();
065: has_identifier = true;
066: break;
067: }
068: }
069: }
070:
071: if (null == primary_key) {
072: primary_key = "id";
073: }
074:
075: // check if the query manager wasn't cached before
076: String cache_name = "GENERIC." + beanClass.getName() + "."
077: + primary_key;
078:
079: query_manager = (AbstractGenericQueryManager<BeanType>) mCache
080: .get(datasource, cache_name);
081:
082: if (query_manager != null) {
083: return query_manager;
084: }
085:
086: // construct the specialized driver class name
087: StringBuilder specialized_name = new StringBuilder(mPackageName);
088: specialized_name.append(StringUtils.encodeClassname(driver));
089:
090: try {
091: try {
092: Class<AbstractGenericQueryManager<BeanType>> specialized_class = (Class<AbstractGenericQueryManager<BeanType>>) Class
093: .forName(specialized_name.toString());
094: Constructor<AbstractGenericQueryManager<BeanType>> specialized_constructor = specialized_class
095: .getConstructor(new Class[] { Datasource.class,
096: String.class, String.class,
097: Class.class, boolean.class });
098:
099: query_manager = specialized_constructor
100: .newInstance(new Object[] { datasource,
101: tableName, primary_key, beanClass,
102: Boolean.valueOf(has_identifier) });
103: } catch (ClassNotFoundException e) {
104: // could not find a specialized class, try to get a generic driver
105: try {
106: // construct the generic driver class name
107: StringBuilder generic_name = new StringBuilder(
108: mPackageName);
109: generic_name.append(GENERIC_DRIVER);
110:
111: Class<AbstractGenericQueryManager<BeanType>> generic_class = (Class<AbstractGenericQueryManager<BeanType>>) Class
112: .forName(generic_name.toString());
113: Constructor<AbstractGenericQueryManager<BeanType>> generic_constructor = generic_class
114: .getConstructor(new Class[] {
115: Datasource.class, String.class,
116: String.class, Class.class,
117: boolean.class });
118:
119: query_manager = generic_constructor
120: .newInstance(new Object[] { datasource,
121: tableName, primary_key, beanClass,
122: Boolean.valueOf(has_identifier) });
123: } catch (ClassNotFoundException e2) {
124: throw new UnsupportedJdbcDriverException(driver, e);
125: }
126: }
127: } catch (InstantiationException e) {
128: throw new UnsupportedJdbcDriverException(driver, e);
129: } catch (IllegalAccessException e) {
130: throw new UnsupportedJdbcDriverException(driver, e);
131: } catch (NoSuchMethodException e) {
132: throw new UnsupportedJdbcDriverException(driver, e);
133: } catch (SecurityException e) {
134: throw new UnsupportedJdbcDriverException(driver, e);
135: } catch (InvocationTargetException e) {
136: if (e.getTargetException() != null) {
137: throw new RuntimeException(e.getTargetException());
138: } else {
139: throw new UnsupportedJdbcDriverException(driver, e);
140: }
141: }
142:
143: return query_manager;
144: }
145: }
|