Package com.sun.gjc.common

Source Code of com.sun.gjc.common.DataSourceObjectBuilder

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package com.sun.gjc.common;

import java.lang.reflect.Method;
import java.util.*;

import com.sun.gjc.util.MethodExecutor;

import javax.resource.ResourceException;

import com.sun.logging.*;

import java.util.logging.Logger;
import java.util.logging.Level;

import com.sun.enterprise.util.i18n.StringManager;
import org.glassfish.internal.api.Globals;
import org.glassfish.internal.api.ClassLoaderHierarchy;

/**
* Utility class, which would create necessary Datasource object according to the
* specification.
*
* @author Binod P.G
* @version 1.0, 02/07/23
* @see com.sun.gjc.common.DataSourceSpec
* @see com.sun.gjc.util.MethodExcecutor
*/
public class DataSourceObjectBuilder implements java.io.Serializable {

    private DataSourceSpec spec;

    private Hashtable driverProperties = null;

    private MethodExecutor executor = null;

    private static Logger _logger;

    static {
        _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
    }

    private static boolean jdbc40;
    private static boolean jdbc41;

    static {
        jdbc40 = detectJDBC40();
        jdbc41 = detectJDBC41();
    }

    private boolean debug = false;

    private static final StringManager sm = StringManager.getManager(
            DataSourceObjectBuilder.class);

    /**
     * Construct a DataSource Object from the spec.
     *
     * @param spec <code> DataSourceSpec </code> object.
     */
    public DataSourceObjectBuilder(DataSourceSpec spec) {
        this.spec = spec;
        executor = new MethodExecutor();
    }

    /**
     * Construct the DataSource Object from the spec.
     *
     * @return Object constructed using the DataSourceSpec.
     * @throws <code>ResourceException</code> if the class is not found or some issue in executing
     *                                        some method.
     */
    public Object constructDataSourceObject() throws ResourceException {
        driverProperties = parseDriverProperties(spec, true);
        Object dataSourceObject = getDataSourceObject();
        Method[] methods = dataSourceObject.getClass().getMethods();
        for (int i = 0; i < methods.length; i++) {
            String methodName = methods[i].getName();
            //Check for driver properties first since some jdbc properties
            //may be supported in form of driver properties
            if (driverProperties.containsKey(methodName.toUpperCase(Locale.getDefault()))) {
                Vector values = (Vector) driverProperties.get(methodName.toUpperCase(Locale.getDefault()));
                executor.runMethod(methods[i], dataSourceObject, values);
            } else if (methodName.equalsIgnoreCase("setUser")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.USERNAME), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setPassword")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.PASSWORD), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setLoginTimeOut")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.LOGINTIMEOUT), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setLogWriter")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.LOGWRITER), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setDatabaseName")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.DATABASENAME), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setDataSourceName")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.DATASOURCENAME), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setDescription")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.DESCRIPTION), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setNetworkProtocol")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.NETWORKPROTOCOL), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setPortNumber")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.PORTNUMBER), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setRoleName")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.ROLENAME), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setServerName")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.SERVERNAME), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setMaxStatements")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.MAXSTATEMENTS), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setInitialPoolSize")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.INITIALPOOLSIZE), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setMinPoolSize")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.MINPOOLSIZE), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setMaxPoolSize")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.MAXPOOLSIZE), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setMaxIdleTime")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.MAXIDLETIME), methods[i], dataSourceObject);

            } else if (methodName.equalsIgnoreCase("setPropertyCycle")) {
                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.PROPERTYCYCLE), methods[i], dataSourceObject);

            }
        }
        return dataSourceObject;
    }

    /**
     * Get the extra driver properties from the DataSourceSpec object and
     * parse them to a set of methodName and parameters. Prepare a hashtable
     * containing these details and return.
     *
     * @param spec <code> DataSourceSpec </code> object.
     * @return Hashtable containing method names and parameters,
     * @throws ResourceException If delimiter is not provided and property string
     *                           is not null.
     */
    public Hashtable parseDriverProperties(DataSourceSpec spec, boolean returnUpperCase)
            throws ResourceException {
        String delim = spec.getDetail(DataSourceSpec.DELIMITER);
        String escape = spec.getDetail(DataSourceSpec.ESCAPECHARACTER);
        String prop = spec.getDetail(DataSourceSpec.DRIVERPROPERTIES);

        if (prop == null || prop.trim().equals("")) {
            return new Hashtable();
        } else if (delim == null || delim.equals("")) {
            String msg = sm.getString("dsob.delim_not_specified");
            throw new ResourceException(msg);
        }else if( escape == null  || escape.equals("")){
            String msg = sm.getString("dsob.escape_char_not_specified");
            throw new ResourceException(msg);
        }
        return parseDriverProperties(prop,escape, delim, returnUpperCase);
    }

    /**
     * parse the driver properties and re-generate name value pairs with unescaped values.
     * @param values driverProperties
     * @param escape escape character
     * @param delimiter delimiter
     * @return Hashtable
     */
    public Hashtable parseDriverProperties(String values, String escape,
                String delimiter, boolean returnUpperCase){
        Hashtable result = new Hashtable();
        String parsedValue = "";
        String name = "";               
        String value = "";
        char escapeChar = escape.charAt(0);
        char delimiterChar = delimiter.charAt(0);
        while (values.length() > 0) {
            if (values.charAt(0) == delimiterChar) {
                if (values.length() > 1 && values.charAt(1) == delimiterChar) {
                    if (values.length() > 2 && values.charAt(2) == delimiterChar) {
                        //Check for first property that does not have a value
                        //There is no value specified for this property.
                        //Store the name or it will be lost
                        if (returnUpperCase) {
                            name = parsedValue.toUpperCase(Locale.getDefault());
                        } else {
                            name = parsedValue;
                        }
                        //no value specified for value
                        parsedValue = "";
                    }
                    value = parsedValue;
                    Vector v = new Vector();
                    v.add(value);
                    result.put(name, v);
                    parsedValue = "";
                    values = values.substring(2);
                } else {
                    if (returnUpperCase) {
                        name = parsedValue.toUpperCase(Locale.getDefault());
                    } else {
                        name = parsedValue;
                    }
                    parsedValue = "";
                    values = values.substring(1);
                }
            } else if (values.charAt(0) == escapeChar) {
                if (values.charAt(1) == escapeChar) {
                    parsedValue += values.charAt(1);
                } else if (values.charAt(1) == delimiterChar) {
                    parsedValue += values.charAt(1);
                }
                values = values.substring(2);
            } else if (values.charAt(0) != escapeChar) {
                parsedValue += values.charAt(0);
                values = values.substring(1);
            }
        }

        return result;
    }

    /**
     * Creates a Datasource object according to the spec.
     *
     * @return Initial DataSource Object instance.
     * @throws <code>ResourceException</code> If class name is wrong or classpath is not set
     *                                        properly.
     */
    private Object getDataSourceObject() throws ResourceException {
        String className = spec.getDetail(DataSourceSpec.CLASSNAME);
        try {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            Class dataSourceClass;
            try {
                dataSourceClass = Class.forName(className, true, cl);
            } catch (ClassNotFoundException cnfe) {
                // OSGi-ed apps can't see lib dir, so try using CommonClassLoader
                cl = Globals.get(ClassLoaderHierarchy.class).getCommonClassLoader();
                dataSourceClass = Class.forName(className, true, cl);
            }
            Object dataSourceObject = dataSourceClass.newInstance();
            return dataSourceObject;
        } catch (ClassNotFoundException cnfe) {
            _logger.log(Level.SEVERE, "jdbc.exc_cnfe_ds", cnfe);
            String msg = sm.getString("dsob.class_not_found", className);
            throw new ResourceException(msg);
        } catch (InstantiationException ce) {
            _logger.log(Level.SEVERE, "jdbc.exc_inst", className);
            String msg = sm.getString("dsob.error_instantiating", className);
            throw new ResourceException(msg);
        } catch (IllegalAccessException ce) {
            _logger.log(Level.SEVERE, "jdbc.exc_acc_inst", className);
            String msg = sm.getString("dsob.access_error", className);
            throw new ResourceException(msg);
        }
    }

    public static boolean isJDBC40() {
        return jdbc40;
    }

    public static boolean isJDBC41() {
        return jdbc41;
    }
   
    /**
     * Check whether the jdbc api version is 4.0 or not.
     *
     * @return boolean
     */
    private static boolean detectJDBC40() {
        boolean jdbc40 = false;
        try {
            Class.forName("java.sql.Wrapper");
            jdbc40 = true;
        } catch (ClassNotFoundException cnfe) {
            if(_logger.isLoggable(Level.FINEST)) {
                _logger.log(Level.FINEST,
                    "could not find Wrapper(available in jdbc-40), jdk supports only jdbc-30");
            }
        }
        return jdbc40;
    }

    /**
     * Detect if jdbc api version is 4.1 or not
     *
     * @return boolean
     */
    private static boolean detectJDBC41() {
        boolean jdbc41 = false;
        try {
            Class.forName("java.sql.PseudoColumnUsage");
            jdbc41 = true;
        } catch (ClassNotFoundException cnfe) {
            if(_logger.isLoggable(Level.FINEST)) {
                _logger.log(Level.FINEST,
                    "could not find PseudoColumnUsage(enum available in jdbc-41)," +
                    " jdk supports jdbc-40 or lesser");
            }
        }
        return jdbc41;
    }
}
TOP

Related Classes of com.sun.gjc.common.DataSourceObjectBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.