org.firebirdsql.gds.ParameterBufferHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaybird-jdk17 Show documentation
Show all versions of jaybird-jdk17 Show documentation
JDBC Driver for the Firebird RDBMS
/*
* Firebird Open Source JavaEE Connector - JDBC Driver
*
* Distributable under LGPL license.
* You may obtain a copy of the License at http://www.gnu.org/copyleft/lgpl.html
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* LGPL License for more details.
*
* This file was created by members of the firebird development team.
* All individual contributions remain the Copyright (C) of those
* individuals. Contributors to this file are either listed here or
* can be obtained from a source control history command.
*
* All rights reserved.
*/
package org.firebirdsql.gds;
import org.firebirdsql.logging.Logger;
import org.firebirdsql.logging.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* This class maps the extended JDBC properties to parameter buffer types (for transaction and database
* parameter buffers). It uses java.lang.reflection
to determine correct type of the parameter
* passed to the {@link java.sql.Driver#connect(String, Properties)} method.
*
* @author Roman Rokytskyy
* @author Mark Rotteveel
* @version 1.0
*/
public class ParameterBufferHelper {
private static final Logger log = LoggerFactory.getLogger(ParameterBufferHelper.class);
private static final DpbParameterType UNKNOWN_DPB_TYPE = new DpbParameterType(null, null, DpbValueType.TYPE_UNKNOWN);
public static final String DPB_PREFIX = "isc_dpb_";
public static final String TPB_PREFIX = "isc_tpb_";
public static final String ISC_DPB_TYPES_RESOURCE = "isc_dpb_types.properties";
private static final Map dpbTypes;
private static final Map dpbParameterTypes;
private static final Map tpbTypes;
/*
* Initialize mappings between various GDS constant names and
* their values. This operation should be executed only once.
*/
static {
final Map tempDpbTypes = new HashMap<>();
final Map tempTpbTypes = new HashMap<>();
Class iscClass = ISCConstants.class;
Field[] fields = iscClass.getFields();
for (Field field : fields) {
if (!field.getType().getName().equals("int"))
continue;
String name = field.getName();
Integer value;
try {
value = (Integer) field.get(null);
} catch (IllegalAccessException iaex) {
continue;
}
if (name.startsWith(DPB_PREFIX)) {
// put the correct parameter name
tempDpbTypes.put(name.substring(DPB_PREFIX.length()), value);
// put the full name to tolerate people's mistakes
tempDpbTypes.put(name, value);
} else if (name.startsWith(TPB_PREFIX)) {
// put the correct parameter name
tempTpbTypes.put(name.substring(TPB_PREFIX.length()), value);
// put the full name to tolerate people's mistakes
tempTpbTypes.put(name, value);
}
}
dpbTypes = Collections.unmodifiableMap(tempDpbTypes);
tpbTypes = Collections.unmodifiableMap(tempTpbTypes);
dpbParameterTypes = Collections.unmodifiableMap(loadDpbParameterTypes());
}
/**
* Get integer value of the DPB key corresponding to the specified name.
*
* @param name
* name of the key.
* @return instance of {@link Integer} corresponding to the specified name
* or null
if value is not known.
*/
public static Integer getDpbKey(String name) {
return dpbTypes.get(name);
}
/**
* Gets the {@link DpbParameterType} for the specified dpb item name (short or long)
*
* @param name
* Name of the dpb item
* @return DpbParameterType
instance, or null
if there is no item with this name
*/
public static DpbParameterType getDpbParameterType(final String name) {
DpbParameterType dpbParameterType = dpbParameterTypes.get(name);
if (dpbParameterType == null) {
// No explicit type defined
Integer dpbKey = getDpbKey(name);
if (dpbKey != null) {
final String canonicalName = name.startsWith(DPB_PREFIX) ? name : DPB_PREFIX + name;
dpbParameterType = new DpbParameterType(canonicalName, dpbKey, DpbValueType.TYPE_UNKNOWN);
}
}
return dpbParameterType;
}
/**
* Get mapping between DPB names and their keys.
*
* @return instance of {@link Map}, where key is the name of DPB parameter,
* value is its DPB key.
*/
public static Map getDpbMap() {
return dpbTypes;
}
public static Object parseDpbString(String name, Object value) {
DpbParameterType type = dpbParameterTypes.get(name);
if (type == null)
type = UNKNOWN_DPB_TYPE;
return type.parseDpbString(value);
}
/**
* Get value of TPB parameter for the specified name. This method tries to
* match string representation of the TPB parameter with its value.
*
* @param name
* string representation of TPB parameter, can have "isc_tpb_"
* prefix.
* @return value corresponding to the specified parameter name or null if
* nothing was found.
*/
public static Integer getTpbParam(String name) {
return tpbTypes.get(name);
}
/**
* Load properties from the specified resource. This method uses the same
* class loader that loaded this class.
*
* @param resource
* path to the resource relative to the root of the
* classloader.
* @return instance of {@link Properties} containing loaded resources or
* null
if resource was not found.
* @throws IOException
* if I/O error occured.
*/
private static Properties loadProperties(String resource) throws IOException {
ClassLoader cl = ParameterBufferHelper.class.getClassLoader();
InputStream in;
// get the stream from the classloader or system classloader
if (cl == null)
in = ClassLoader.getSystemResourceAsStream(resource);
else
in = cl.getResourceAsStream(resource);
if (in == null)
throw new IOException("Unable to load resource file " + resource);
try {
Properties props = new Properties();
props.load(in);
return props;
} finally {
in.close();
}
}
/**
* Load mapping between DPB key and their parameter types.
*/
private static Map loadDpbParameterTypes() {
Properties props;
try {
props = loadProperties(ISC_DPB_TYPES_RESOURCE);
} catch (IOException ex) {
log.error("Could not load " + ISC_DPB_TYPES_RESOURCE, ex);
return Collections.emptyMap();
}
final Map tempDpbParameterTypes = new HashMap<>();
for (Map.Entry