org.openanzo.jdbc.opgen.RdbStatement.java Source code

Java tutorial

Introduction

Here is the source code for org.openanzo.jdbc.opgen.RdbStatement.java

Source

/*******************************************************************************
 * Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * File:        $Source: /cvsroot/slrp/common/com.ibm.adtech.jdbc.utils/src/com/ibm/adtech/jdbc/utils/opgen/RdbStatement.java,v $
 * Created by:  Joe Betz
 * Created on:  9/30/2005
 * Revision:   $Id: RdbStatement.java 176 2007-07-31 14:22:30Z mroy $
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Cambridge Semantics Incorporated - Fork to Anzo
 *******************************************************************************/
package org.openanzo.jdbc.opgen;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Provides XML deserialization and accessors for rdf statements (SQL, DDL, etc.) for use in composing PreparedStatementProvider compatable .sql files and
 * generating java rdf statement wrappers.
 * 
 * @author Joe Betz
 * 
 */
public class RdbStatement {

    static final String element = "preparedstatement";

    static final String nameAttribute = "name";

    static final String inputsAttribute = "inputs";

    static final String outputsAttribute = "outputs";

    static final String resultsAttribute = "results";

    static final String templateParamsAttribute = "templateParams";

    static final String PREPARE = "prepare";

    String name;

    String sqlPackageName;

    String sql;

    List<Parameter> inputs;

    List<Parameter> outputs;

    List<Parameter> templateParams;

    Result results;

    boolean prepare = true;

    /**
     * Create a new RdbStatement
     * 
     * @param sqlPackageName
     *            name of package
     * @param name
     *            name of prepared statement
     * @param sql
     *            SQL query text
     * @param inputs
     *            inputs to the query
     * @param outputs
     *            outputs expected from the query
     * @param templateParams
     *            set of template parameters for the query
     * @param results
     *            results type for query
     * @param prepare
     *            true if statement should be prepared, otherwise use callable statement
     */
    public RdbStatement(String sqlPackageName, String name, String sql, List<Parameter> inputs,
            List<Parameter> outputs, List<Parameter> templateParams, Result results, boolean prepare) {
        this.sqlPackageName = sqlPackageName;
        this.name = name;
        this.sql = sql;
        this.inputs = inputs;
        this.outputs = outputs;
        this.templateParams = templateParams;
        this.results = results;
        this.prepare = prepare;
        initialize();
    }

    // make a best effort to get the text within a node.
    private static String getText(Node n) {
        NodeList nl = n.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node n2 = nl.item(i);
            if (n2.getNodeType() == Node.TEXT_NODE) {
                String text = n2.getNodeValue();
                if (text.trim().length() > 0) {
                    return text;
                }
            } else if (n2.getNodeType() == Node.CDATA_SECTION_NODE) {
                return n2.getNodeValue();
            } else {
                return getText(n);
            }
        }
        return null;
    }

    private static final Pattern pattern = Pattern.compile("(\\s+)");

    /**
     * Create a new RdbStatement from the given XML emement data
     * 
     * @param sqlPackageName
     *            package name for statement
     * @param xmlElement
     *            XML element containing data
     */
    public RdbStatement(String sqlPackageName, Element xmlElement) {
        this.sqlPackageName = sqlPackageName;
        if (!xmlElement.getNodeName().equals(element))
            throw new InvalidParameterException("XML element not of type '" + element + "'");
        sql = getText(xmlElement);
        if (sql == null)
            throw new InvalidParameterException("Node has no text: " + xmlElement);
        if (sql.trim().equals("EMPTY")) {
            sql = "";
        }
        Node nameNode = xmlElement.getAttributes().getNamedItem(nameAttribute);
        if (nameNode == null)
            throw new InvalidParameterException(
                    "'" + nameAttribute + "' is a required attribute for '" + element + "' element.");
        name = nameNode.getNodeValue();
        Node inputsNode = xmlElement.getAttributes().getNamedItem(inputsAttribute);
        if (inputsNode != null) {
            String paramList = inputsNode.getNodeValue();
            inputs = getParams(paramList);
        } else {
            inputs = new ArrayList<Parameter>(0);
        }
        Node templateParamsNode = xmlElement.getAttributes().getNamedItem(templateParamsAttribute);
        if (templateParamsNode != null) {
            String paramList = templateParamsNode.getNodeValue();
            templateParams = getParams(paramList);
        } else {
            templateParams = new ArrayList<Parameter>(0);
        }
        Node outputsNode = xmlElement.getAttributes().getNamedItem(outputsAttribute);
        if (outputsNode != null) {
            String paramList = outputsNode.getNodeValue();
            outputs = getParams(paramList);
        } else {
            outputs = new ArrayList<Parameter>(0);
        }
        Node resultsNode = xmlElement.getAttributes().getNamedItem(resultsAttribute);
        if (resultsNode != null) {
            results = Result.getResultsEnum(resultsNode);
        }
        Node dpNode = xmlElement.getAttributes().getNamedItem(PREPARE);
        if (dpNode != null) {
            prepare = Boolean.parseBoolean(dpNode.getNodeValue());
        }
        initialize();
    }

    private void initialize() {
        if (results == null)
            results = Result.NONE;
        if (results == Result.ROW && outputs.size() <= 1)
            throw new InvalidParameterException(name
                    + ": ROW return type not allowed when there is zero or one outputs, use VALUE or ITERATOR instead.");
        if (results == Result.COUNTER && outputs.size() > 0)
            throw new InvalidParameterException(name
                    + ": COUNTER return type not allowed when there is one our more outputs, use VALUE,ROW or ITERATOR instead.");
    }

    private static List<Parameter> getParams(String paramList) {
        List<Parameter> list = new ArrayList<Parameter>();
        if (paramList.length() > 0) {
            String[] params = paramList.split(",");
            for (int i = 0; i < params.length; i++) {
                String param = params[i].trim();
                String[] vals = pattern.split(param);
                String type = vals[0];
                String name = vals[1];
                boolean canBeNull = !type.startsWith("+");
                if (!canBeNull) {
                    type = type.substring(1);
                }
                ParameterType pType = ParameterType.valueOf(type);
                if (pType != null) {
                    list.add(new Parameter(name, pType, canBeNull));
                } else {
                    throw new RuntimeException(type + " type is invalid:" + paramList);
                }
            }
        }
        return list;
    }

    /**
     * Get the name of the statement
     * 
     * @return the name of the statement
     */
    public String getName() {
        return name;
    }

    /**
     * Get the qualified name of the statement
     * 
     * @return the qualified name of the statement
     */
    public String getQualifiedName() {
        if (sqlPackageName != "") {
            return sqlPackageName + "." + name;
        }
        return name;
    }

    /**
     * Capitalize the name of the statement
     * 
     * @return capitalized name of the statement
     */
    public String capitalizedName() {
        return org.apache.commons.lang.StringUtils.capitalize(name);
    }

    /**
     * Return if the provided string is a primitive value type
     * 
     * @param string
     *            type of value for which to determine primitive nature
     * @return if the provided string is a primitive value type
     */
    public static boolean isPrimitive(String string) {
        return string.equals("short") || string.equals("byte") || string.equals("boolean") || string.equals("long")
                || string.equals("int") || string.equals("char");
    }

    /**
     * Get the SQL query text for this statement
     * 
     * @return the SQL query text for this statement
     */
    public String getSql() {
        return sql;
    }

    /**
     * @return the dontPrepare
     */
    public boolean getPrepare() {
        return prepare;
    }

    /**
     * Get the input parameters for this statement
     * 
     * @return the input parameters for this statement
     */
    public List<Parameter> getInputs() {
        return inputs;
    }

    /**
     * Get the output parameters for this statement
     * 
     * @return the output parameters for this statement
     */
    public List<Parameter> getOutputs() {
        return outputs;
    }

    /**
     * Get the template parameters for this statement
     * 
     * @return the template parameters for this statement
     */
    public List<Parameter> getParams() {
        return templateParams;
    }

    /**
     * Get the return type for this statement
     * 
     * @return the return type for this statement
     */
    public String getReturnType() {
        if (results == Result.NONE) {
            return "void";
        } else if (results == Result.ITERATOR) {
            return "org.openanzo.jdbc.utils.ClosableIterator";
        } else if (results == Result.ROW) {
            return capitalizedName() + "Result";
        } else if (results == Result.VALUE) {
            return getValueReturnType(false);
        } else if (results == Result.COUNTER) {
            return "int";
        } else if (results == Result.IDENTITY) {
            return "Long";
        }
        throw new InvalidParameterException("Not a valid enumeration value: " + results.getValue());
    }

    /**
     * Determine if this statement has input parameters
     * 
     * @return if this statement has input parameters
     */
    public boolean hasInputParamType() {
        return (inputs.size() > 1);
    }

    /**
     * Get the Interface name for this statement's parameters
     * 
     * @return the Interface name for this statements parameters
     */
    public String getInputParamInterface() {
        return capitalizedName() + "Params";
    }

    /**
     * Get the Implementation name for this statement's parameters
     * 
     * @return the Implementation name for this statement's parameters
     */
    public String getInputParamImpl() {
        return capitalizedName() + "ParamsImpl";
    }

    /**
     * Get the interface name for this statement's results
     * 
     * @return the interface name for this statement's results
     */
    public String getResultsInterface() {
        return capitalizedName() + "Result";
    }

    /**
     * Get the implementation name for this statement's results
     * 
     * @return the implementation name for this statement's results
     */
    public String getResultsImpl() {
        return capitalizedName() + "ResultImpl";
    }

    String inputParamSigniture = null;

    /**
     * Get the full string representing for the input parameters to this statement
     * 
     * @return the full string representing for the input parameters to this statement
     */
    public String getInputParamSigniture() {
        if (inputParamSigniture == null) {
            inputParamSigniture = buildSignitureString(inputs);
        }
        return inputParamSigniture;
    }

    String inputExceptionSignature = null;

    /**
     * Get the full string representing for the input parameters to this statement
     * 
     * @return the full string representing for the input parameters to this statement
     */
    public String getInputExceptionSignature() {
        if (inputExceptionSignature == null) {
            inputExceptionSignature = buildExceptionSignitureString(inputs);
        }
        return inputExceptionSignature;
    }

    String templateExceptionSignature = null;

    /**
     * Get the full string representing for the input parameters to this statement
     * 
     * @return the full string representing for the input parameters to this statement
     */
    public String getTemplateExceptionSignature() {
        if (templateExceptionSignature == null) {
            templateExceptionSignature = buildExceptionSignitureString(templateParams);
        }
        return templateExceptionSignature;
    }

    String inputParams = null;

    /**
     * Get the string representing for the input parameters to this statement
     * 
     * @return the string representing for the input parameters to this statement
     */
    public String getInputParams() {
        if (inputParams == null) {
            inputParams = buildParamString(inputs);
        }
        return inputParams;
    }

    /**
     * Return true if this statement has template parameters
     * 
     * @return true if this statement has template parameters
     */
    public boolean hasTemplateParams() {
        return templateParams.size() > 0;
    }

    String templateParamSigniture = null;

    /**
     * Get the full string representing for the template parameters to this statement
     * 
     * @return the full string representing for the template parameters to this statement
     */
    public String getTemplateParamSigniture() {
        if (templateParamSigniture == null) {
            templateParamSigniture = buildSignitureString(templateParams);
        }
        return templateParamSigniture;
    }

    String templateParamsString = null;

    /**
     * Get the string representing for the template parameters to this statement
     * 
     * @return the string representing for the template parameters to this statement
     */
    public String getTemplateParams() {
        if (templateParamsString == null) {
            templateParamsString = buildParamString(templateParams);
        }
        return templateParamsString;
    }

    String templateParamsJavadocString = null;

    /**
     * Get the javadoc representing for the template parameters to this statement
     * 
     * @return the javadoc representing for the template parameters to this statement
     */
    public String getTemplateParamsJavadoc() {
        if (templateParamsJavadocString == null) {
            templateParamsJavadocString = buildJavadocParamString(templateParams);
        }
        return templateParamsJavadocString;
    }

    String inputParamsJavadocString = null;

    /**
     * Get the javadoc representing for the input parameters to this statement
     * 
     * @return the javadoc representing for the input parameters to this statement
     */
    public String getInputParamsJavadoc() {
        if (inputParamsJavadocString == null) {
            inputParamsJavadocString = buildJavadocParamString(inputs);
        }
        return inputParamsJavadocString;
    }

    /**
     * Return true if this statement has input parameters
     * 
     * @return true if this statement has input parameters
     */
    public boolean hasInputParams() {
        return inputs.size() > 0;
    }

    private String buildParamString(List<Parameter> params) {
        StringBuilder inputParamsBuf = new StringBuilder();
        for (Iterator<Parameter> inIter = params.iterator(); inIter.hasNext();) {
            Parameter param = inIter.next();
            inputParamsBuf.append(param.getName());
            if (inIter.hasNext()) {
                inputParamsBuf.append(", ");
            }
        }
        return inputParamsBuf.toString();
    }

    private String buildJavadocParamString(List<Parameter> params) {
        StringBuilder inputParamsBuf = new StringBuilder();
        for (Iterator<Parameter> inIter = params.iterator(); inIter.hasNext();) {
            Parameter param = inIter.next();
            inputParamsBuf.append("\n    *@param ");
            inputParamsBuf.append(param.getName());
            inputParamsBuf.append(" template parameter");
        }
        return inputParamsBuf.toString();
    }

    private String buildSignitureString(List<Parameter> params) {
        StringBuilder inputParamSignitureBuf = new StringBuilder();
        for (Iterator<Parameter> inIter = params.iterator(); inIter.hasNext();) {
            Parameter param = inIter.next();
            inputParamSignitureBuf.append(param.getJavaType(false));
            inputParamSignitureBuf.append(" ");
            inputParamSignitureBuf.append(param.getName());
            if (inIter.hasNext()) {
                inputParamSignitureBuf.append(", ");
            }
        }
        return inputParamSignitureBuf.toString();
    }

    private String buildExceptionSignitureString(List<Parameter> params) {
        StringBuilder inputParamSignitureBuf = new StringBuilder();
        for (Iterator<Parameter> inIter = params.iterator(); inIter.hasNext();) {
            Parameter param = inIter.next();
            if (param.isPrimitive()) {
                inputParamSignitureBuf.append("\"" + param.getName() + "=\"+(" + param.getName() + ")");
            } else {
                inputParamSignitureBuf.append("\"" + param.getName() + "=\"+((");
                inputParamSignitureBuf.append(param.getName());
                inputParamSignitureBuf.append("!=null)?");
                inputParamSignitureBuf.append(param.getName());
                inputParamSignitureBuf.append(".toString():\"null\")");
            }
            if (inIter.hasNext()) {
                inputParamSignitureBuf.append(" + \",\" +");
            }
        }
        return inputParamSignitureBuf.toString();
    }

    /**
     * Return true if this statement expects results
     * 
     * @return true if this statement expects results
     */
    public boolean hasReturn() {
        return !getReturnType().equals("void");
    }

    /**
     * Get the return type for this statement
     * 
     * @param box
     *            should this type be boxed
     * @return the return type for this statement
     */
    public String getValueReturnType(boolean box) {
        Parameter param = getFirstOutput();
        return param.getJavaType(box);
    }

    /**
     * get the resultset property
     * 
     * @return resultset property
     */
    public String getResultSetProperty() {
        Parameter param = getFirstOutput();
        return param.getResultSetProperty();
    }

    /**
     * Get the javatype for this statement
     * 
     * @param box
     *            should the type be boxed
     * @return the javatype for this statement
     */
    public String getJavaType(boolean box) {
        return getFirstOutput().getJavaType(box);
    }

    /**
     * Get the jdbc type for this statement
     * 
     * @param box
     *            should the type be boxed
     * 
     * @return the jdbc type for this statement
     */
    public String getJdbcType(boolean box) {
        Parameter firstOutput = getFirstOutput();
        return firstOutput.getJdbcType();
    }

    /**
     * 
     * @return true if the result type is primitive
     */
    public boolean isPrimitive() {
        return getFirstOutput().isPrimitive();
    }

    private Parameter getFirstOutput() {
        Iterator<Parameter> iter = outputs.iterator();
        if (!iter.hasNext())
            throw new InvalidParameterException("No outputs specified");
        return iter.next();
    }

    /**
     * Get the result object for the statement
     * 
     * @return the result object for the statement
     */
    public Result getResults() {
        return results;
    }

    /**
     * Class the contains an input/output/template parameter
     */
    public static class Parameter {
        static HashMap<String, String> toPrimitive = new HashMap<String, String>();
        static {
            toPrimitive.put("Long", "long");
            toPrimitive.put("Integer", "int");
            toPrimitive.put("Byte", "byte");
            toPrimitive.put("Character", "char");
            toPrimitive.put("Short", "short");
            toPrimitive.put("Float", "float");
            toPrimitive.put("Boolean", "boolean");
            toPrimitive.put("Double", "double");
        }

        final String name;

        final ParameterType type;

        final boolean canBeNull;

        /**
         * Create a new parameter with the given type
         * 
         * @param name
         *            name of the parameter
         * @param type
         *            type of the parameter
         * @param canBeNull
         *            can this parameter take null values
         */
        public Parameter(String name, ParameterType type, boolean canBeNull) {
            this.name = name;
            this.type = type;
            this.canBeNull = canBeNull;
        }

        /**
         * Get the name of the parameter
         * 
         * @return the name of the parameter
         */
        public String getName() {
            return name;
        }

        /**
         * Get the JavaType for the parameter
         * 
         * @param box
         *            should primitives be boxed
         * @return the JavaType for the parameter
         */
        public String getJavaType(boolean box) {
            if (!box && !canBeNull) {
                String jt = toPrimitive.get(type.getJavaType());
                if (jt == null) {
                    jt = type.getJavaType();
                }
                return jt;
            } else {
                return type.getJavaType();
            }
        }

        /**
         * Get the JdbcType for the parameter
         * 
         * @return the JdbcType for the parameter
         */
        public String getJdbcType() {
            return type.getJdbcType();
        }

        /**
         * Get the result set property
         * 
         * @return the result set property
         */
        public String getResultSetProperty() {
            return type.getResultSetType();
        }

        /**
         * Get the RDB property
         * 
         * @return the RDB property
         */
        public String getRdbProperty() {
            return org.apache.commons.lang.StringUtils.capitalize(name);
        }

        /**
         * Get whether or not this parameter can be bull
         * 
         * @return whether or not this parameter can be bull
         */
        public boolean canBeNull() {
            return canBeNull;
        }

        /**
         * Is this parameter a primitive
         * 
         * @return true if primitive
         */
        public boolean isPrimitive() {
            if (!canBeNull) {
                String jt = toPrimitive.get(type.getJavaType());
                return (jt != null);
            } else {
                return false;
            }
        }
    }
}