Package org.mc4j.ems.connection

Source Code of org.mc4j.ems.connection.ConnectionFactory$DirectoryFilter

/*
* Copyright 2002-2004 Greg Hinkle
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.mc4j.ems.connection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mc4j.ems.connection.settings.ConnectionSettings;
import org.mc4j.ems.connection.support.ConnectionProvider;
import org.mc4j.ems.connection.support.classloader.ClassLoaderFactory;
import org.mc4j.ems.connection.support.metadata.*;

import java.io.File;
import java.io.FilenameFilter;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* @author Greg Hinkle (ghinkle@users.sourceforge.net), Apr 5, 2005
* @version $Revision: 1.2 $($Author: ghinkl $ / $Date: 2006/04/12 19:11:33 $)
*/
public class ConnectionFactory {

    private static final String BROAD_SEARCH_PROPERTY = "mc4j.ems.fileSearchBroad";
    private static final int DEFAULT_SEARCH_DEPTH = 6;
    private static final String SEARCH_DEPTH_PROPERTY = "mc4j.ems.fileSearchDepth";

    private boolean broadSearch = false;
    private int searchDepth = DEFAULT_SEARCH_DEPTH;


    private static Log log = LogFactory.getLog(ConnectionFactory.class);

    public static final ConnectionTypeDescriptor[] CONNECTION_DESCRIPTORS =
            new ConnectionTypeDescriptor[]{
                    new JBossConnectionTypeDescriptor(),
                    new Tomcat55ConnectionTypeDescriptor(),
                    new JDMKConnectionTypeDescriptor(),
                    new J2SE5ConnectionTypeDescriptor(),
                    new JSR160ConnectionTypeDescriptor(),
                    new GeronimoConnectionTypeDescriptor(),
                    new Mx4jConnectionTypeDescriptor(),
                    new Oc4jConnectionTypeDescriptor(),
                    new PramatiConnectionTypeDescriptor(),
                    new SJSASConnectionTypeDescriptor(),
                    new WeblogicConnectionTypeDescriptor(),
                    new Weblogic9ConnectionTypeDescriptor(),
                    new Weblogic9Jsr77ConnectionTypeDescriptor(),
                    new WebsphereConnectionTypeDescriptor(),
                    new WebsphereStudioConnectionTypeDescriptor()};

    // TODO GH: Move to a SPI model allowing new types to be added later?
    // TODO GH: Perhaps go to a more externalized descriptor based model?
    public static List<ConnectionTypeDescriptor> getConnectionTypes() {
        return Arrays.asList(CONNECTION_DESCRIPTORS);
    }

    public ConnectionFactory() {
        if (System.getProperty(BROAD_SEARCH_PROPERTY) != null) {
            broadSearch = Boolean.valueOf(System.getProperty(BROAD_SEARCH_PROPERTY));
        }
        if (System.getProperty(SEARCH_DEPTH_PROPERTY) != null) {
            searchDepth = Integer.parseInt(System.getProperty(SEARCH_DEPTH_PROPERTY));
        }
    }


    public EmsConnection connect(ConnectionSettings connectionSettings) {

        log.info("Connecting to " + connectionSettings.toString());
       
        String className = connectionSettings.getConnectionType().getConnectionNodeClassName();

        try {

            // TODO GH: Does this need to be configurable per connection?
            ClassLoader loader = ClassLoaderFactory.getInstance().buildClassLoader(connectionSettings);


            log.debug("Loading connection class from ClassLoader [" + loader + "] ConnectionProvider class [" + className + "]");

            // TODO GH: Add intelligent classloader layer here that can either work
            // directly against current classloader or build a non-delegating child
            // to override with connection specific classes           
            Class clazz = Class.forName(className, false, loader);


            ConnectionProvider connectionProvider =
                    (ConnectionProvider) clazz.newInstance();

            connectionProvider.initialize(connectionSettings);
            return connectionProvider.connect();

        } catch (IllegalAccessException e) {
            throw new ConnectionException("Could not access ConnectionClass", e);
        } catch (InstantiationException e) {
            throw new ConnectionException("Could not instantiate ConnectionClass", e);
        } catch (ClassNotFoundException e) {
            throw new ConnectionException("Could not find ConnectionClass " + className, e);
        }
    }


    /**
     * This will find server classes for a ConnectionSettings by using the supplied
     * LibraryURI of the ConnectionSettings and searching for the ConnectClassPathEntries
     * of the ConnectionType supplied with the settings.
     * <p/>
     * This method should only be called once. If the entries need to be reset, you should
     * first clear the settings' classpath entries. This method appends class path entries
     * to the existing list.
     *
     * @param connectionSettings the ConnectionSettings to update with recommeneded class
     *                           path entries
     */
    public void discoverServerClasses(ConnectionSettings connectionSettings) {
        if (connectionSettings.getLibraryURI() != null) {
            long start = System.currentTimeMillis();
            String[] serverFiles = connectionSettings.getConnectionType().getConnectionClasspathEntries();

            // No server file dependencies
            if (serverFiles == null)
                return;

            File serverInstall = new File(connectionSettings.getLibraryURI());
            if (!serverInstall.exists())
                throw new LoadException("Supplied server installation does not exist " + connectionSettings.getLibraryURI());


            List<File> foundFiles = new ArrayList<File>();

            for (String serverFile : serverFiles) {
                if (broadSearch && serverFile.indexOf('/') >= 0) {
                    serverFile = serverFile.substring(serverFile.lastIndexOf('/')+1);
                }


                log.debug("Searching for library " + serverFile);
                File[] matchedFiles = null;
                try {
                    if (serverFile.indexOf('/') >= 0) {
                        matchedFiles = findDeepFiles(serverInstall, serverFile);
                    } else {
                        File file = findFile(serverInstall, serverFile);
                        if (file != null)
                            matchedFiles = new File[]{file};
                    }
                } catch (Exception e) {
                    log.info("Library dependency not found " + serverFile, e);
                }

                if (matchedFiles != null) {
                    for (File matchedFile : matchedFiles) {
                        if (matchedFile != null && !foundFiles.contains(matchedFile)) {
                            foundFiles.add(matchedFile);
                            log.debug("Library dependency resolved " + matchedFile.getAbsolutePath());
                        }
                    }
                } else {
                    log.info("Connection library dependancy [" + serverFile+ "] not found  in directory: " + serverInstall);
                }
            }

            if (connectionSettings.getClassPathEntries() == null)
                connectionSettings.setClassPathEntries(foundFiles);
            else
                connectionSettings.getClassPathEntries().addAll(foundFiles);

            log.info("Discovered libraries in " + (System.currentTimeMillis() - start) + " ms");
        }
    }


    private File findFile(File directory, String filename) {
        return findFile(directory, filename, 1);
    }

    private File findFile(File directory, String filename, int depth) {
        if (depth > searchDepth)
            return null;
        File[] children = directory.listFiles();
        if (children == null)
            return null;
        for (File child : children) {
            if (child.isDirectory()) {
                File result = findFile(child, filename, depth + 1);
                if (result != null)
                    return result;
            } else {
                if (filename.equalsIgnoreCase(child.getName()))
                    return child;
            }
        }
        return null;
    }


    private File[] findDeepFiles(File directory, String filename) {
        if (filename.startsWith("/"))
            filename = filename.substring(1);
        int in = filename.indexOf("/");
        if (in < 0) {

            if (filename.equals("*")) {
                return directory.listFiles();
            } else {
                File match = getChild(directory, filename);
                if (match == null)
                    return null;
                else
                    return new File[]{match};
            }

        } else {
            String dir = filename.substring(0, in);
            String restOfName = filename.substring(in + 1, filename.length());

            if (dir.equals("*")) {
                File[] children = directory.listFiles(new DirectoryFilter());
                if (children != null) {
                    for (File child : children) {
                        File[] childDir = findDeepFiles(child, restOfName);
                        if (childDir != null) {
                            return childDir;
                        }
                    }
                }
                log.debug("Could not find " + directory.getAbsolutePath() + " :: " + restOfName);
                return null;
            } else {
                File childDir = getChild(directory, dir);
                if (childDir == null) {
                    log.debug("Could not find " + directory.getAbsolutePath() + " :: " + restOfName);
                    return null;
                } else {
                    return findDeepFiles(childDir, restOfName);
                }
            }
        }
    }

    private static class DirectoryFilter implements FileFilter {
        public boolean accept(File pathname) {
            return pathname.isDirectory();
        }

    }

    public File getChild(File directory, final String childName) {
        if (directory == null)
            return null;
        if (!directory.exists())
            return null;
        File[] children = directory.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return childName.equals(name);
            }
        });
        if (children.length == 1) {
            return children[0];
        } else {
            //log.info("Connection library dependancy [" + childName + "] not found  in directory: " + directory.getAbsolutePath());
            return null;
        }
    }

}
TOP

Related Classes of org.mc4j.ems.connection.ConnectionFactory$DirectoryFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.