001/* ----------------------------------------------------------------------------
002   The Kiwi Toolkit - A Java Class Library
003   Copyright (C) 1998-2004 Mark A. Lindner
004
005   This library is free software; you can redistribute it and/or
006   modify it under the terms of the GNU General Public License as
007   published by the Free Software Foundation; either version 2 of the
008   License, or (at your option) any later version.
009
010   This library is distributed in the hope that it will be useful,
011   but WITHOUT ANY WARRANTY; without even the implied warranty of
012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013   General Public License for more details.
014
015   You should have received a copy of the GNU General Public License
016   along with this library; if not, write to the Free Software
017   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018   02111-1307, USA.
019 
020   The author may be contacted at: mark_a_lindner@yahoo.com
021   ----------------------------------------------------------------------------
022   $Log: PluginLocator.java,v $
023   Revision 1.8  2004/05/12 18:03:42  markl
024   javadoc updates
025
026   Revision 1.7  2004/03/15 06:47:46  markl
027   Major rewrite to allow multiple instantiations of a given plugin, and
028   reload capability.
029
030   Revision 1.6  2003/01/19 09:31:22  markl
031   Javadoc & comment header updates.
032
033   Revision 1.5  2002/01/04 22:18:25  markl
034   Throw exception rather than returning null if manifest entry not found
035
036   Revision 1.4  2001/08/28 21:38:31  markl
037   More fixes to defer GUI-stuff when display not available.
038
039   Revision 1.3  2001/08/28 20:28:21  markl
040   Fixes to defer access to Toolkit for situations where no X Display is
041   available.
042
043   Revision 1.2  2001/03/18 07:58:50  markl
044   Added javadoc.
045
046   Revision 1.1  2001/03/12 10:21:00  markl
047   New classes.
048   ----------------------------------------------------------------------------
049*/
050
051package kiwi.util.plugin;
052
053import java.awt.Image;
054import java.io.*;
055import java.util.*;
056import java.util.jar.*;
057import javax.swing.ImageIcon;
058
059import kiwi.util.*;
060
061/** A utility class for locating plugins in JAR files. This class is the
062 * heart of the Kiwi plugin API.
063 * <p>
064 * A plugin consists of one or more classes that implement the plugin itself
065 * (with one of those classes being the main or entry-point class). These
066 * classes are stored in a JAR file. The JAR file Manifest must contain an
067 * entry for the plugin. This entry identifies the plugin entry-point class
068 * and other information about the plugin. Here is an example entry:
069 * <p>
070 * <pre>
071 * Name: com/foo/imaging/BlurFilter.class
072 * PluginName: Blur Filter
073 * PluginType: Image Filter
074 * PluginIcon: com/foo/imaging/icons/BlurFilter.gif
075 * PluginHelpURL: http://dystance.net/filters/blur.html
076 * PluginVersion: 1.1.2
077 * </pre>
078 * <p>
079 * The <code>Name</code> field identifies the file in the JAR that is the
080 * plugin entry-point class. The <code>PluginName</code> field provides a
081 * textual name for the plugin, and the <code>PluginType</code> field
082 * identifies the type of the plugin (the meaning of which is
083 * application-dependent). These fields must be present in the entry, whereas
084 * the remaining fields are optional.
085 * <p>
086 * The <code>PluginDescriptio</code> field provides a brief description of the
087 * plugin (and may optionally include a copyright message or other related
088 * information). <code>PluginIcon</code> identifies an icon image for the
089 * plugin. Finally, <code>PluginVersion</code> specifies the version number of
090 * the plugin.
091 * <p>
092 *
093 * @since Kiwi 1.3
094 *
095 * @author Mark Lindner
096 */
097
098public class PluginLocator
099  {
100  private PluginContext context;
101  private ResourceDecoder decoder;
102  private Vector forbiddenPackages, restrictedPackages;
103
104  /** Construct a new <code>PluginLocator</code> with the specified plugin
105   * context.
106   *
107   * @param context The <code>PluginContext</code> for this plugin locator.
108   */
109  
110  public PluginLocator(PluginContext context)
111    {
112    decoder = new ResourceDecoder();
113
114    this.context = context;
115
116    restrictedPackages = new Vector();
117    forbiddenPackages = new Vector();
118
119    addRestrictedPackage("java.*");
120    addRestrictedPackage("javax.*");
121    addRestrictedPackage("kiwi.*");
122    }
123
124  /** Add a package to the locator's list of restricted packages. Plugins are
125   * allowed to access classes in restricted packages, but they are not allowed
126   * to declare classes that belong to those packages.
127   *
128   * @param pkg The package name.
129   */
130  
131  public void addRestrictedPackage(String pkg)
132    {
133    synchronized(restrictedPackages)
134      {
135      if(! restrictedPackages.contains(pkg))
136        restrictedPackages.addElement(pkg);
137      }
138    }
139
140  /** Add a package to the locator's list of forbidden packages. Plugins are
141   * not allowed to access classes in forbidden packages, nor are they allowed
142   * to declare classes that belong to those packages.
143   *
144   * @param pkg The package name.
145   */
146
147  public void addForbiddenPackage(String pkg)
148    {
149    synchronized(forbiddenPackages)
150      {
151      if(! forbiddenPackages.contains(pkg))
152        forbiddenPackages.addElement(pkg);
153      }
154    }
155
156  /** Create a Plugin object for the given plugin archive.
157   *
158   * @param jarFile The plugin archive.
159   *
160   * @return The <code>Plugin</code>, if successfully created, or
161   * <code>null</code> otherwise.
162   */
163  
164  public Plugin loadPlugin(String jarFile, String type) throws PluginException
165    {
166    Plugin plugin = new Plugin(this, jarFile, type);
167
168    return(plugin);
169    }
170
171  /** Create a Plugin object for the given plugin archive.
172   *
173   * @param jarFile The plugin archive.
174   *
175   * @return The <code>Plugin</code>, if successfully created, or
176   * <code>null</code> otherwise.
177   */
178  
179  public Plugin loadPlugin(File jarFile, String type) throws PluginException
180    {
181    return(loadPlugin(jarFile.getAbsolutePath(), type));
182    }
183
184  /*
185   */
186
187  PluginContext getContext()
188    {
189    return(context);
190    }
191
192  /*
193   */
194
195  ResourceDecoder getDecoder()
196    {
197    return(decoder);
198    }
199
200  /*
201   */
202
203  PluginClassLoader createClassLoader()
204    {
205    return(new PluginClassLoader(forbiddenPackages, restrictedPackages));
206    }
207  
208  }
209
210/* end of source file */