blob: 88a0950b9255162b503096461350936eec59b8bd [file] [log] [blame]
/*
* Copyright (c) 2003, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.jdbcra.common;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Vector;
import java.util.StringTokenizer;
import java.util.Enumeration;
import com.sun.jdbcra.util.MethodExecutor;
import jakarta.resource.ResourceException;
import java.util.logging.Logger;
import java.util.logging.Level;
/**
* Utility class, which would create necessary Datasource object according to the
* specification.
*
* @version 1.0, 02/07/23
* @author Binod P.G
* @see com.sun.jdbcra.common.DataSourceSpec
* @see com.sun.jdbcra.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 = Logger.getAnonymousLogger();
}
private boolean debug = false;
/**
* 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);
Object dataSourceObject = getDataSourceObject();
Method[] methods = dataSourceObject.getClass().getMethods();
for (int i=0; i < methods.length; i++) {
String methodName = methods[i].getName();
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);
} else if (driverProperties.containsKey(methodName.toUpperCase())){
Vector values = (Vector) driverProperties.get(methodName.toUpperCase());
executor.runMethod(methods[i],dataSourceObject, values);
}
}
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.
*/
private Hashtable parseDriverProperties(DataSourceSpec spec) throws ResourceException{
String delim = spec.getDetail(DataSourceSpec.DELIMITER);
String prop = spec.getDetail(DataSourceSpec.DRIVERPROPERTIES);
if ( prop == null || prop.trim().equals("")) {
return new Hashtable();
} else if (delim == null || delim.equals("")) {
throw new ResourceException ("Delimiter is not provided in the configuration");
}
Hashtable properties = new Hashtable();
delim = delim.trim();
String sep = delim+delim;
int sepLen = sep.length();
String cache = prop;
Vector methods = new Vector();
while (cache.indexOf(sep) != -1) {
int index = cache.indexOf(sep);
String name = cache.substring(0,index);
if (name.trim() != "") {
methods.add(name);
cache = cache.substring(index+sepLen);
}
}
Enumeration allMethods = methods.elements();
while (allMethods.hasMoreElements()) {
String oneMethod = (String) allMethods.nextElement();
if (!oneMethod.trim().equals("")) {
String methodName = null;
Vector parms = new Vector();
StringTokenizer methodDetails = new StringTokenizer(oneMethod,delim);
for (int i=0; methodDetails.hasMoreTokens();i++ ) {
String token = (String) methodDetails.nextToken();
if (i==0) {
methodName = token.toUpperCase();
} else {
parms.add(token);
}
}
properties.put(methodName,parms);
}
}
return properties;
}
/**
* 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 {
Class dataSourceClass = Class.forName(className);
Object dataSourceObject = dataSourceClass.newInstance();
return dataSourceObject;
} catch(ClassNotFoundException cfne){
_logger.log(Level.SEVERE, "jdbc.exc_cnfe_ds", cfne);
throw new ResourceException("Class Name is wrong or Class path is not set for :" + className);
} catch(InstantiationException ce) {
_logger.log(Level.SEVERE, "jdbc.exc_inst", className);
throw new ResourceException("Error in instantiating" + className);
} catch(IllegalAccessException ce) {
_logger.log(Level.SEVERE, "jdbc.exc_acc_inst", className);
throw new ResourceException("Access Error in instantiating" + className);
}
}
}