#94804 Support datasource migration for Project Migration easylookup_98426_root_tempheadmarker
authorjbaker@netbeans.org
Sun, 15 Apr 2007 01:40:51 +0000
changeset 582c3b39f2b7df1
parent 581 1810e6380ff1
child 583 a91714b2afc9
#94804 Support datasource migration for Project Migration

Integrated initial version.
visualweb.dataconnectivity/src/org/netbeans/modules/visualweb/dataconnectivity/naming/DatabaseSettingsImporter.java
     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 +}