001: /*
002: * The contents of this file are subject to the Mozilla Public License
003: * Version 1.1 (the "License"); you may not use this file except in
004: * compliance with the License. You may obtain a copy of the License at
005: * http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
009: * License for the specific language governing rights and limitations
010: * under the License.
011: *
012: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
013: *
014: * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
015: * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
016: *
017: * Contributor(s):
018: * Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
019: *
020: * If you didn't download this code from the following link, you should check
021: * if you aren't using an obsolete version: http://www.isqlviewer.com
022: */
023: package org.isqlviewer.sql;
024:
025: import java.io.File;
026: import java.io.FileInputStream;
027: import java.io.IOException;
028: import java.util.Collections;
029: import java.util.Map;
030: import java.util.Properties;
031: import java.util.Set;
032: import java.util.TreeMap;
033:
034: import org.isqlviewer.sql.platform.OracleRegistrar;
035: import org.isqlviewer.util.LocalMessages;
036: import org.isqlviewer.util.LoggableObject;
037:
038: /**
039: * Factory class for providing mappings of fully qualified class names to specific PlatformRegistrar instances.
040: * <p>
041: * Instaces of this class will inspect a file called 'registrar.mappings' in the 'user.dir' of the Java runtime. This
042: * file can contain extra registration handlers if needed by providing a standard Java properties file and a mapping of
043: * class names of the JDBC driver to the class name of the PlatformRegistrar implementation for that Driver.
044: *
045: * @author Mark A. Kobold <mkobold at isqlviewer dot com>
046: * @version 1.0
047: */
048: public final class RegistrarFactory extends LoggableObject {
049:
050: private static final Map<String, String> defaultMappings;
051:
052: static {
053: TreeMap<String, String> mappings = new TreeMap<String, String>();
054: mappings.put("oracle.jdbc.driver.OracleDriver",
055: OracleRegistrar.class.getName());
056: defaultMappings = Collections.synchronizedSortedMap(mappings);
057: }
058:
059: private static final RegistrarFactory sharedInstance = new RegistrarFactory();
060:
061: public static RegistrarFactory createInstance() {
062:
063: return new RegistrarFactory();
064: }
065:
066: public static RegistrarFactory getSharedInstance() {
067:
068: return sharedInstance;
069: }
070:
071: private Map<String, String> classMappings = null;
072: private Map<String, PlatformRegistrar> registrarCache = new TreeMap<String, PlatformRegistrar>();
073: private static final String RESOURCE_BUNDLE = "org.isqlviewer.sql.ResourceBundle";
074: private static final LocalMessages messages = new LocalMessages(
075: RESOURCE_BUNDLE, JdbcService.class);
076:
077: private RegistrarFactory() {
078:
079: File mappingFile = new File(new File(System
080: .getProperty("user.dir")), "registrar.mappings");
081: if (mappingFile.exists() && mappingFile.canRead()) {
082: Properties properties = new Properties();
083: FileInputStream inputStream = null;
084: try {
085: inputStream = new FileInputStream(mappingFile);
086: properties.load(inputStream);
087: classMappings = new TreeMap<String, String>();
088: Set<Map.Entry<Object, Object>> set = properties
089: .entrySet();
090: for (Map.Entry<Object, Object> entry : set) {
091: classMappings.put((String) entry.getKey(),
092: (String) entry.getValue());
093: }
094: } catch (IOException error) {
095: debug(
096: messages
097: .getMessage("RegistrarFactory.failed_to_load_registrar_mappings"),
098: error);
099: }
100: }
101: }
102:
103: /**
104: * Looks up a platform registrar by connection class name.
105: * <p>
106: *
107: * @param connectionClass of the JDBC platform being used.
108: * @return instance of PlatformRegistrar for the driver class, <tt>null</tt> if unknown.
109: */
110: public PlatformRegistrar lookupRegistrar(String connectionClass) {
111:
112: PlatformRegistrar instance = registrarCache
113: .get(connectionClass);
114: if (instance == null) {
115: instance = createNewInstance(classMappings, connectionClass);
116: if (instance == null) {
117: instance = createNewInstance(defaultMappings,
118: connectionClass);
119: }
120: if (instance != null) {
121: registrarCache.put(connectionClass, instance);
122: }
123: }
124: return instance;
125: }
126:
127: private PlatformRegistrar createNewInstance(
128: Map<String, String> classMap, String connectionClass) {
129:
130: if (classMap != null) {
131: String className = classMap.get(connectionClass);
132: if (className != null && className.trim().length() > 0) {
133: try {
134: Class<?> clazz = Class.forName(className);
135: return (PlatformRegistrar) clazz.newInstance();
136: } catch (ClassNotFoundException e) {
137: error(messages
138: .format(
139: "RegistrarFactory.registrar_class_not_found",
140: connectionClass));
141: } catch (InstantiationException e) {
142: error(
143: messages
144: .format(
145: "RegistrarFactory.registrar_class_failed_to_initialize",
146: connectionClass), e);
147: } catch (IllegalAccessException e) {
148: error(messages
149: .format(
150: "RegistrarFactory.registrar_class_not_accessible",
151: connectionClass));
152: }
153: }
154: }
155: return null;
156: }
157:
158: }
|