From a6df2de41953e10db1527e54acd734c0f0a1fa28 Mon Sep 17 00:00:00 2001 From: James Moger Date: Mon, 10 Nov 2014 11:59:09 -0500 Subject: Implement DAO externalized statement loading based on runtime Mode --- .../com/iciql/DaoClasspathStatementProvider.java | 95 ++++++++++++++++++++++ src/main/java/com/iciql/DaoProxy.java | 13 ++- src/main/java/com/iciql/DaoStatementProvider.java | 36 ++++++++ src/main/java/com/iciql/Db.java | 33 ++++++-- 4 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/iciql/DaoClasspathStatementProvider.java create mode 100644 src/main/java/com/iciql/DaoStatementProvider.java (limited to 'src/main') diff --git a/src/main/java/com/iciql/DaoClasspathStatementProvider.java b/src/main/java/com/iciql/DaoClasspathStatementProvider.java new file mode 100644 index 0000000..b1bbe14 --- /dev/null +++ b/src/main/java/com/iciql/DaoClasspathStatementProvider.java @@ -0,0 +1,95 @@ +/* + * Copyright 2014 James Moger. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.iciql; + +import java.io.InputStream; +import java.util.Properties; + +import com.iciql.Iciql.Mode; + +/** + * Loads DAO statements from Properties resource files the classpath. + * + * @author James Moger + * + */ +public class DaoClasspathStatementProvider implements DaoStatementProvider { + + private final Properties externalStatements; + + public DaoClasspathStatementProvider() { + externalStatements = load(); + } + + /** + * Returns the list of statement resources to try locating. + * + * @return + */ + protected String[] getStatementResources() { + return new String[] { "/iciql.properties", "/iciql.xml", "/conf/iciql.properties", "/conf/iciql.xml" }; + } + + /** + * Loads the first statement resource found on the classpath. + * + * @return the loaded statements + */ + private Properties load() { + + Properties props = new Properties(); + for (String resource : getStatementResources()) { + + InputStream is = null; + + try { + is = DaoProxy.class.getResourceAsStream(resource); + + if (is != null) { + + if (resource.toLowerCase().endsWith(".xml")) { + // load an .XML statements file + props.loadFromXML(is); + } else { + // load a .Properties statements file + props.load(is); + } + + break; + } + + } catch (Exception e) { + throw new IciqlException(e, "Failed to parse {0}", resource); + } finally { + try { + is.close(); + } catch (Exception e) { + } + } + + } + return props; + } + + @Override + public String getStatement(String idOrStatement, Mode mode) { + final String modePrefix = "%" + mode.name().toLowerCase() + "."; + String value = externalStatements.getProperty(idOrStatement, idOrStatement); + value = externalStatements.getProperty(modePrefix + idOrStatement, value); + return value; + } + +} diff --git a/src/main/java/com/iciql/DaoProxy.java b/src/main/java/com/iciql/DaoProxy.java index db5f911..cafd6f7 100644 --- a/src/main/java/com/iciql/DaoProxy.java +++ b/src/main/java/com/iciql/DaoProxy.java @@ -72,7 +72,7 @@ final class DaoProxy implements InvocationHandler, Dao { * @return a proxy object */ @SuppressWarnings("unchecked") - X buildProxy() { + X build() { if (!daoInterface.isInterface()) { throw new IciqlException("Dao {0} must be an interface!", daoInterface.getName()); @@ -115,12 +115,14 @@ final class DaoProxy implements InvocationHandler, Dao { } else if (method.isAnnotationPresent(SqlQuery.class)) { String sql = method.getAnnotation(SqlQuery.class).value(); - return executeQuery(method, args, sql); + String statement = db.getDaoStatementProvider().getStatement(sql, db.getMode()); + return executeQuery(method, args, statement); } else if (method.isAnnotationPresent(SqlStatement.class)) { String sql = method.getAnnotation(SqlStatement.class).value(); - return executeStatement(method, args, sql); + String statement = db.getDaoStatementProvider().getStatement(sql, db.getMode()); + return executeStatement(method, args, statement); } else { @@ -220,6 +222,11 @@ final class DaoProxy implements InvocationHandler, Dao { objects.add(value); + if (!isArray) { + // we are not returning an array so we break + // the loop and return the first result + break; + } } } catch (SQLException e) { diff --git a/src/main/java/com/iciql/DaoStatementProvider.java b/src/main/java/com/iciql/DaoStatementProvider.java new file mode 100644 index 0000000..7e7522a --- /dev/null +++ b/src/main/java/com/iciql/DaoStatementProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright 2014 James Moger. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.iciql; + +import com.iciql.Iciql.Mode; + +/** + * Defines the interface for retrieving externalized DAO statements. + * + * @author James Moger + * + */ +public interface DaoStatementProvider { + + /** + * Returns the statement associated with the id. + * + * @param idOrStatement + * @param mode + * @return the statement + */ + String getStatement(String idOrStatement, Mode mode); +} diff --git a/src/main/java/com/iciql/Db.java b/src/main/java/com/iciql/Db.java index 794417e..7413c8f 100644 --- a/src/main/java/com/iciql/Db.java +++ b/src/main/java/com/iciql/Db.java @@ -74,6 +74,7 @@ public class Db implements AutoCloseable { private boolean skipCreate; private boolean autoSavePoint = true; + private DaoStatementProvider daoStatementProvider; static { TOKENS = Collections.synchronizedMap(new WeakIdentityHashMap()); @@ -102,6 +103,7 @@ public class Db implements AutoCloseable { } dialect = getDialect(databaseName, conn.getClass().getName()); dialect.configureDialect(this); + daoStatementProvider = new NoExternalDaoStatements(); } /** @@ -237,7 +239,30 @@ public class Db implements AutoCloseable { */ @SuppressWarnings("resource") public X open(Class daoClass) { - return new DaoProxy(this, daoClass).buildProxy(); + return new DaoProxy(this, daoClass).build(); + } + + /** + * Returns the DAO statement provider. + * + * @return the DAO statement provider + */ + public DaoStatementProvider getDaoStatementProvider() { + return daoStatementProvider; + } + + /** + * Sets the DAO statement provider. + * + * @param statementProvider + */ + public void setDaoStatementProvider(DaoStatementProvider statementProvider) { + if (statementProvider == null) { + throw new IciqlException("You must provide a valid {0} instance!", + DaoStatementProvider.class.getSimpleName()); + } + + this.daoStatementProvider = statementProvider; } /** @@ -841,14 +866,12 @@ public class Db implements AutoCloseable { } /** - * - * @author James Moger - * + * Default DAO statement provider. */ class NoExternalDaoStatements implements DaoStatementProvider { @Override - public String getStatement(String idOrStatement) { + public String getStatement(String idOrStatement, Mode mode) { return idOrStatement; } -- cgit v1.2.3