1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/visualweb.dataconnectivity/src/org/netbeans/modules/visualweb/dataconnectivity/naming/DatabaseSettingsImporter.java Sun Apr 15 01:40:51 2007 +0000
1.3 @@ -0,0 +1,402 @@
1.4 +/*
1.5 + * The contents of this file are subject to the terms of the Common Development
1.6 + * and Distribution License (the License). You may not use this file except in
1.7 + * compliance with the License.
1.8 + *
1.9 + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
1.10 + * or http://www.netbeans.org/cddl.txt.
1.11 + *
1.12 + * When distributing Covered Code, include this CDDL Header Notice in each file
1.13 + * and include the License file at http://www.netbeans.org/cddl.txt.
1.14 + * If applicable, add the following below the CDDL Header, with the fields
1.15 + * enclosed by brackets [] replaced by your own identifying information:
1.16 + * "Portions Copyrighted [year] [name of copyright owner]"
1.17 + *
1.18 + * The Original Software is NetBeans. The Initial Developer of the Original
1.19 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
1.20 + * Microsystems, Inc. All Rights Reserved.
1.21 + */
1.22 +
1.23 +package org.netbeans.modules.visualweb.dataconnectivity.naming;
1.24 +
1.25 +import org.netbeans.modules.visualweb.dataconnectivity.utils.*;
1.26 +import java.io.File;
1.27 +import java.io.FilenameFilter;
1.28 +import java.io.IOException;
1.29 +import java.net.URL;
1.30 +import java.text.MessageFormat;
1.31 +import java.util.ArrayList;
1.32 +import java.util.Hashtable;
1.33 +import java.util.Iterator;
1.34 +import java.util.Locale;
1.35 +import java.util.ResourceBundle;
1.36 +import java.util.Set;
1.37 +import java.util.Stack;
1.38 +import java.util.TreeMap;
1.39 +import java.util.jar.Attributes;
1.40 +import java.util.jar.JarFile;
1.41 +import javax.crypto.Cipher;
1.42 +import javax.crypto.SecretKey;
1.43 +import javax.crypto.spec.SecretKeySpec;
1.44 +import javax.naming.NameParser;
1.45 +import javax.xml.parsers.ParserConfigurationException;
1.46 +import javax.xml.parsers.SAXParser;
1.47 +import javax.xml.parsers.SAXParserFactory;
1.48 +import org.netbeans.api.db.explorer.ConnectionManager;
1.49 +import org.netbeans.api.db.explorer.DatabaseConnection;
1.50 +import org.netbeans.api.db.explorer.DatabaseException;
1.51 +import org.netbeans.api.db.explorer.JDBCDriver;
1.52 +import org.netbeans.api.db.explorer.JDBCDriverManager;
1.53 +import org.netbeans.modules.visualweb.dataconnectivity.datasource.DataSourceResolver;
1.54 +import org.netbeans.modules.visualweb.dataconnectivity.model.DataSourceInfo;
1.55 +import org.openide.ErrorManager;
1.56 +import org.openide.util.Exceptions;
1.57 +import org.xml.sax.SAXException;
1.58 +import org.xml.sax.SAXNotRecognizedException;
1.59 +import org.xml.sax.helpers.DefaultHandler;
1.60 +
1.61 +/**
1.62 + *
1.63 + * @author John Baker
1.64 + */
1.65 +public class DatabaseSettingsImporter {
1.66 +
1.67 + private static DatabaseSettingsImporter databaseSettingsImporter;
1.68 + public static final String ROOT_CTX_TAG = "rootContext"; // NOI18N
1.69 + public static final String CTX_TAG = "context"; // NOI18N
1.70 + public static final String OBJ_TAG = "object"; // NOI18N
1.71 + public static final String ARG_TAG = "arg"; // NOI18N
1.72 + public static final String NAME_ATTR = "name"; // NOI18N
1.73 + public static final String CLASS_ATTR = "class"; // NOI18N
1.74 + public static final String VALUE_ATTR = "value"; // NOI18N
1.75 + private static final int TAB_WIDTH = 4;
1.76 + private DesignTimeContext parent;
1.77 + private String ctxName;
1.78 + private TreeMap map;
1.79 + private Hashtable env;
1.80 + private NameParser nameParser = DesignTimeNameParser.getInstance();
1.81 + private String ctxPathName;
1.82 + private File userCtxFile;
1.83 + private boolean initMode; /* used only by initial context ctor, signals not to
1.84 + * call saveContext during InitialContext construction
1.85 + */
1.86 +
1.87 + private static ResourceBundle rb = ResourceBundle.getBundle("com.sun.rave.naming.Bundle", // NOI18N
1.88 + Locale.getDefault());
1.89 +
1.90 + /** Creates a new instance of DatabaseImporter */
1.91 + private DatabaseSettingsImporter() {
1.92 + }
1.93 +
1.94 + public static DatabaseSettingsImporter getInstance() {
1.95 + if (databaseSettingsImporter == null){
1.96 + databaseSettingsImporter = new DatabaseSettingsImporter();
1.97 + }
1.98 + return databaseSettingsImporter;
1.99 + }
1.100 +
1.101 +
1.102 + public boolean locateAndRegisterDrivers() {
1.103 + String driversPath = locateDrivers();
1.104 + if (locateDrivers().equals(""))
1.105 + return false;
1.106 +
1.107 + registerDrivers(driversToRegister(driversPath));
1.108 + return true;
1.109 + }
1.110 +
1.111 + private String locateDrivers() {
1.112 + String driverLocation;
1.113 +
1.114 + driverLocation = System.getProperty("netbeans.user") + File.separator + File.separator + "jdbc-drivers";
1.115 + File driverDir = new File(driverLocation);
1.116 + if (driverDir.exists())
1.117 + return driverLocation;
1.118 + else
1.119 + return "";
1.120 + }
1.121 +
1.122 + private File[] driversToRegister(String driversPath) {
1.123 + File driverDir = new File(driversPath);
1.124 +
1.125 + File[] drivers = driverDir.listFiles(
1.126 + new FilenameFilter() {
1.127 + public boolean accept(File dir, String name) {
1.128 + return name.endsWith(".jar") || name.endsWith(".zip");
1.129 + }
1.130 + });
1.131 +
1.132 + return drivers;
1.133 + }
1.134 +
1.135 + private void registerDriver(File driverJar) {
1.136 + String[] drivers = (String[]) DriverListUtil.getDrivers().toArray(new String[DriverListUtil.getDrivers().size()]);
1.137 +
1.138 + try {
1.139 + URL url = (URL)driverJar.toURL();
1.140 +
1.141 + JarFile jf = new JarFile(driverJar);
1.142 +
1.143 + String drv;
1.144 + Set drvs = DriverListUtil.getDrivers();
1.145 + Iterator it = drvs.iterator();
1.146 + while (it.hasNext()) {
1.147 + drv = (String) it.next();
1.148 + if (jf.getEntry(drv.replace('.', '/') + ".class") != null) {//NOI18N
1.149 + String driverName = DriverListUtil.findFreeName(DriverListUtil.getName(drv));
1.150 + JDBCDriver driver = JDBCDriver.create(driverName, driverName, drv, new URL[] {driverJar.toURI().toURL()});
1.151 + try {
1.152 + JDBCDriverManager.getDefault().addDriver(driver);
1.153 + } catch (DatabaseException e) {
1.154 + ErrorManager.getDefault().notify(e);
1.155 + }
1.156 + }
1.157 + }
1.158 + jf.close();
1.159 +
1.160 + } catch (IOException ioe) {
1.161 + ErrorManager.getDefault().notify(ioe);
1.162 + }
1.163 + }
1.164 +
1.165 +
1.166 + private void registerDrivers(File[] driverFiles) {
1.167 + for (File drv : driverFiles) {
1.168 + registerDriver(drv);
1.169 +
1.170 + }
1.171 + }
1.172 +
1.173 +
1.174 + // Locate $userdir/$release/context.xml
1.175 + // Open context.xml
1.176 + // Read context.xml
1.177 + // get connection information store in a map, return map
1.178 + // check if driver has been registered
1.179 + // read map and register connection(s)
1.180 +
1.181 + public boolean locateAndRegisterConnections() {
1.182 + File contextFile = locateContextFile();
1.183 + if (contextFile == null)
1.184 + return false;
1.185 +
1.186 + registerConnections(contextFile);
1.187 + return true;
1.188 + }
1.189 +
1.190 + private File locateContextFile() {
1.191 + File contextReleaseRoot = new File(System.getProperty("netbeans.user") + File.separator + File.separator + "config" + File.separator + File.separator);
1.192 +
1.193 + File[] contextReleaseDir = contextReleaseRoot.listFiles();
1.194 +
1.195 + File[] contextReleaseDirFiles = contextReleaseDir[0].listFiles();
1.196 + if (contextReleaseDirFiles[0].exists())
1.197 + return contextReleaseDirFiles[0];
1.198 + else
1.199 + return null;
1.200 + }
1.201 +
1.202 + private void registerConnections(File contextFile) {
1.203 + ArrayList <DataSourceInfo> dataSources = createDataSourceInfoFromCtx(contextFile);
1.204 +
1.205 + try {
1.206 + // JdbcDriverInfo jdbcInfo = JdbcDriverInfoManager.getInstance().getCurrentJdbcDriverInfo();
1.207 + // dsInfo = DataSourceInfoManager.getInstance().getDataSourceInfoByName(itemSelected);
1.208 +
1.209 + Iterator it = dataSources.iterator();
1.210 + DataSourceInfo dsInfo = null;
1.211 +
1.212 + // From each Data Source, add a connection to DB Explorer
1.213 + while (it.hasNext()) {
1.214 + dsInfo = ((DataSourceInfo)it.next());
1.215 + String username = dsInfo.getUsername();
1.216 + String password = dsInfo.getPassword();
1.217 + JDBCDriver drvs = DataSourceResolver.getInstance().findMatchingDriver(dsInfo.getDriverClassName());
1.218 + DatabaseConnection dbconn = DatabaseConnection.create(drvs, dsInfo.getUrl(), username, username.toUpperCase(), password, true); // NOI18N
1.219 + ConnectionManager.getDefault().addConnection(dbconn);
1.220 + }
1.221 +
1.222 + } catch (DatabaseException de) {
1.223 + de.printStackTrace();
1.224 + }
1.225 + }
1.226 +
1.227 + static private SecretKey secretKey = null;
1.228 +
1.229 + static final private char[] secretKeyHex =
1.230 + {'D','6','0','7','5','E','2','9','8','A','4','9','6','2','5','1'};
1.231 +
1.232 + private static SecretKey getSecretKey() {
1.233 + if (secretKey == null) {
1.234 + byte[] encodedKey = new byte[secretKeyHex.length/2];
1.235 + for (int i = 0; i < encodedKey.length; i++) {
1.236 + encodedKey[i] = hexToByte(secretKeyHex[i*2], secretKeyHex[i*2+1]);
1.237 + }
1.238 + secretKey = new SecretKeySpec(encodedKey, "DES"); // NOI18N
1.239 + }
1.240 +
1.241 + return secretKey;
1.242 + }
1.243 +
1.244 + private static final String hexString = "0123456789ABCDEF"; // NOI18N
1.245 +
1.246 + private static byte hexToByte(char char1, char char2) {
1.247 + return (byte)((hexString.indexOf(char1) << 4) + hexString.indexOf(char2));
1.248 + }
1.249 +
1.250 + private String decryptPassword(String password) {
1.251 +
1.252 + if (password == null) {
1.253 + return null;
1.254 + }
1.255 +
1.256 + try {
1.257 + char[] hexChars = password.toCharArray();
1.258 +
1.259 + byte[] encryptedBytes = new byte[hexChars.length/2];
1.260 + for (int i = 0; i < encryptedBytes.length; i++) {
1.261 + encryptedBytes[i] = hexToByte(hexChars[i*2], hexChars[i*2+1]);
1.262 + }
1.263 + Cipher cipher = Cipher.getInstance("DES"); // NOI18N
1.264 + cipher.init(Cipher.DECRYPT_MODE, getSecretKey());
1.265 + byte[] passwordBytes = cipher.doFinal(encryptedBytes);
1.266 + return new String(passwordBytes);
1.267 + } catch (Exception e) {
1.268 + e.printStackTrace();
1.269 + return "";
1.270 + }
1.271 + }
1.272 +
1.273 + private DataSourceInfo createDataSourceInfo(ArrayList<DataSourceInfo> dataSource) {
1.274 + Iterator it = dataSource.iterator();
1.275 + String dsName = null;
1.276 + String schema = null;
1.277 + String driverClassName = null;
1.278 + String driverUrl = null;
1.279 + String username = null;
1.280 + String password = null;
1.281 + String[] dataSourceContents = null;
1.282 +
1.283 + int pos = 0;
1.284 + int i = 0;
1.285 + while (it.hasNext()) {
1.286 + // exclude unneeded items of data source
1.287 + if ((pos != 1) && (pos != 3) && (pos != 6))
1.288 + dataSourceContents[i++] = (String)it.next();
1.289 +
1.290 + pos++;
1.291 + }
1.292 +
1.293 + // create data source info
1.294 + password = decryptPassword(password);
1.295 + return new DataSourceInfo(dsName, driverClassName, driverUrl, "", username, password);
1.296 + }
1.297 +
1.298 + private ArrayList<DataSourceInfo> createDataSourceInfoFromCtx(File contextFile) {
1.299 + ArrayList <DataSourceInfo> dsInfo = null;
1.300 + ArrayList dataSources = null;
1.301 +
1.302 + try {
1.303 + dataSources = parseContextFile(contextFile);
1.304 + } catch (ParserConfigurationException ex) {
1.305 + Exceptions.printStackTrace(ex);
1.306 + } catch (SAXException ex) {
1.307 + Exceptions.printStackTrace(ex);
1.308 + } catch (IOException ex) {
1.309 + Exceptions.printStackTrace(ex);
1.310 + }
1.311 +
1.312 + // extract data source info from each datasource ArrayList
1.313 + Iterator its = dataSources.iterator();
1.314 + ArrayList dataSource = null;
1.315 + Iterator it = null;
1.316 +
1.317 + while (its.hasNext()) {
1.318 + dataSource = (ArrayList)its.next();
1.319 + it = dataSource.iterator();
1.320 +
1.321 + while (it.hasNext()) {
1.322 + dsInfo.add(createDataSourceInfo((ArrayList)it.next()));
1.323 + }
1.324 + }
1.325 + return dsInfo;
1.326 +}
1.327 +
1.328 +
1.329 +
1.330 + private ArrayList parseContextFile(File userCtxFile) throws ParserConfigurationException, SAXException,
1.331 + IOException {
1.332 + SAXParserFactory factory = SAXParserFactory.newInstance();
1.333 + factory.setNamespaceAware(true);
1.334 + factory.setValidating(false);
1.335 + SAXParser parser = factory.newSAXParser();
1.336 + final ArrayList dataSources = new ArrayList();
1.337 +
1.338 + parser.parse(userCtxFile, new DefaultHandler() {
1.339 +
1.340 + private Stack ctxStack = new Stack();
1.341 + private ArrayList args = new ArrayList();
1.342 + private String objectName;
1.343 + private String className;
1.344 + public void startElement(String uri, String localName, String qName,
1.345 + Attributes attributes) throws SAXException {
1.346 + if (qName.equals(CTX_TAG)) {
1.347 +
1.348 + String nameValue = attributes.getValue(NAME_ATTR);
1.349 + if (nameValue == null) {
1.350 + throw new SAXException(
1.351 + MessageFormat.format(rb.getString("MISSING_ATTR"),
1.352 + new Object[] { "name" })); // NOI18N
1.353 + }
1.354 +
1.355 + } else if (qName.equals(OBJ_TAG)) {
1.356 + args.clear();
1.357 + objectName = attributes.getValue(NAME_ATTR);
1.358 + className = attributes.getValue(CLASS_ATTR);
1.359 + if (objectName == null) {
1.360 + throw new SAXException(
1.361 + MessageFormat.format(rb.getString("MISSING_ATTR"),
1.362 + new Object[] { "name" })); // NOI18N
1.363 + } else
1.364 + args.add(objectName);
1.365 + } else if (qName.equals("arg")) { // NOI18N
1.366 + String classValue = attributes.getValue(CLASS_ATTR);
1.367 + if (classValue == null) {
1.368 + throw new SAXException(
1.369 + MessageFormat.format(rb.getString("MISSING_ATTR"),
1.370 + new Object[] { "class" })); // NOI18N
1.371 + }
1.372 + String valueValue = attributes.getValue(VALUE_ATTR);
1.373 + args.add(new ArgPair(classValue, valueValue));
1.374 + } else {
1.375 + throw new SAXNotRecognizedException(qName);
1.376 + }
1.377 +
1.378 + dataSources.add(args);
1.379 + }
1.380 +
1.381 +
1.382 +
1.383 + });
1.384 +
1.385 + return dataSources;
1.386 + }
1.387 +
1.388 +
1.389 +
1.390 + private class ArgPair {
1.391 + private String clazz;
1.392 + private String value;
1.393 + ArgPair(String clazz, String value) {
1.394 + this.clazz = clazz;
1.395 + this.value = value;
1.396 + }
1.397 + String getClazz() {
1.398 + return clazz;
1.399 + }
1.400 + String getValue() {
1.401 + return value;
1.402 + }
1.403 + }
1.404 +
1.405 +}