aboutsummaryrefslogtreecommitdiffstats
path: root/bak/net/java/games/util/plugins/PluginLoader.java~1~
blob: 9d41467fdcbf0fe001a2c2dd61923e59397dafa9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
 * PluginLodaer.java
 *
 * Created on April 18, 2003, 11:32 AM
 */
/*****************************************************************************
 * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistribution of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materails provided with the distribution.
 *
 * Neither the name Sun Microsystems, Inc. or the names of the contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind.
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMEN, ARE HEREBY EXCLUDED.  SUN MICROSYSTEMS, INC. ("SUN") AND
 * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
 * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.  IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
 * INCIDENTAL OR PUNITIVE DAMAGES.  HOWEVER CAUSED AND REGARDLESS OF THE THEORY
 * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed or intended for us in
 * the design, construction, operation or maintenance of any nuclear facility
 *
 *****************************************************************************/
package net.java.games.util.plugins;

/**
 *
 * @author  jeff
 */
import java.io.*;
import java.net.*;

/** This class is used internally by the Plugin system.
 * End users of the system are unlikely to need to be aware
 * of it.
 *
 *
 * This is the class loader used to keep the namespaces of
 * different plugins isolated from each other and from the
 * main app code. One plugin loader is created per Jar
 * file in the sub-directory tree of the plugin directory.
 *
 * In addition to isolating java classes this loader also isolates
 * DLLs such that plugins with conflicting DLL names may be
 * used by simply placing the plugin and its associated DLL
 * in a  sub-folder of its own.
 *
 * This class also currently implements methods for testing
 * classes for inheritance of superclasses or interfaces.
 * This code is genericly useful and should really be moved
 * to a seperate ClassUtils class.
 * @author Jeffrey Kesselman
 */
public class PluginLoader extends URLClassLoader {
    static final boolean DEBUG = false;
    File parentDir;
    boolean localDLLs = true;
    /** Creates a new instance of PluginLodaer
     * @param jf The JarFile to load the Plugins from.
     * @throws MalformedURLException Will throw this exception if jf does not refer to a
     * legitimate Jar file.
     */
    public PluginLoader(File jf) throws MalformedURLException {
        super(new URL[] {jf.toURL()});
        parentDir = jf.getParentFile();
        if (System.getProperty("net.java.games.util.plugins.nolocalnative")
            !=null){
          localDLLs = false;
        }
    }

    /** This method is queried by the System.loadLibrary()
     * code to find the actual native name and path to the
     * native library to load.
     *
     * This subclass implementation of this method ensures that
     * the native library will be loaded from, and only from,
     * the parent directory of the Jar file this loader was
     * created to support.  This allows different Plugins
     * with supporting DLLs of the same name to co-exist, each
     * in their own subdirectory.
     * @param libname The JNI name of the native library to locate.
     * @return Returns a string describing the actual loation of the
     * native library in the native file system.
     */
    protected String findLibrary(String libname){
      if (localDLLs) {
        String libpath = parentDir.getPath() + File.separator +
            System.mapLibraryName(libname);
        if (DEBUG) {
          System.out.println("Returning libname of: " + libpath);
        }
        return libpath;
      } else {
        return super.findLibrary(libname);
      }
    }

    /** This function is called as part of scanning the Jar for
     * plugins.  It checks to make sure the class passed in is
     * a legitimate plugin, which is to say that it meets
     * the following criteria:
     *
     * (1) Is not itself an interface
     * (2) Implements the Plugin marker interface either directly
     *    or through inheritance.
     *
     * interface, either
     * @param pc The potential plug-in class to vette.
     * @return Returns true if the class meets the criteria for a
     * plugin. Otherwise returns false.
     */
    public boolean attemptPluginDefine(Class pc){
        return ((!pc.isInterface()) && classImplementsPlugin(pc));
    }

    private boolean classImplementsPlugin(Class testClass){
        if (testClass == null) return false; // end of tree
        if (DEBUG) {
            System.out.println("testing class "+testClass.getName());
        }
        Class[] implementedInterfaces = testClass.getInterfaces();
        for(int i=0;i<implementedInterfaces.length;i++){
            if (DEBUG) {
                System.out.println("examining interface: "+implementedInterfaces[i]);
            }
            if (implementedInterfaces[i]==Plugin.class) {
                if (DEBUG) {
                    System.out.println("returning true from classImplementsPlugin");
                }
                return true;
            }
        }
        for(int i=0;i<implementedInterfaces.length;i++){
            if (classImplementsPlugin(implementedInterfaces[i])){
                return true;
            }
        }
        return classImplementsPlugin(testClass.getSuperclass());
    }

}