KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ungoverned > moduleloader > Module


1 /*
2  * ModuleLoader - A generic, policy-driven class loader.
3  * Copyright (c) 2004, Richard S. Hall
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  * * Neither the name of the ungoverned.org nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * Contact: Richard S. Hall (heavy@ungoverned.org)
33  * Contributor(s):
34  *
35 **/

36 package org.ungoverned.moduleloader;
37
38 import java.security.AccessController JavaDoc;
39 import java.security.PrivilegedAction JavaDoc;
40 import java.util.*;
41
42 /**
43  * <p>
44  * The <tt>Module</tt> class is a grouping mechanism for application classes
45  * and resources. Conceptually, most applications are grouped into
46  * entities such as JAR files (containing classes and resources) and native
47  * libraries. In some cases, these entities are core application classes and
48  * resources, while in other cases, these entities are ancillary, such as
49  * dynamically loaded plug-ins. Applications place some level of semantics
50  * onto these types of entities or <i>modules</i>, but for the <tt>ModuleLoader</tt>,
51  * no particular semantics are attached to modules (other than they are a grouping
52  * mechanism for classes and resources). This means that the application
53  * is free to map itself into modules any way that is appropriate.
54  * </p>
55  * <p>
56  * A module has the following features:
57  * </p>
58  * <ul>
59  * <li>A unique identifier within the scope of its <tt>ModuleManager</tt>.
60  * </li>
61  * <li>A set of key-value attribute pairs.
62  * </li>
63  * <li>A set of resource sources from which it is possible to
64  * retrieve classes and resources.
65  * </li>
66  * <li>A set of native library sources from which it is possible
67  * to retrieve native libraries.
68  * </li>
69  * </ul>
70  * <p>
71  * A module's identifier must be unique within the scope of its
72  * <tt>ModuleManager</tt>, but there is no meaning associated with it. The
73  * set of attribute-value pairs attached to the module have no meaning to
74  * the <tt>ModuleManager</tt>, nor does it consult them at all. The point
75  * of these attributes is to attach meta-data for use by
76  * <a HREF="SearchPolicy.html"><tt>SearchPolicy</tt></a> implementations.
77  * Attributes are represented as an array of <tt>Object</tt>
78  * arrays, i.e., <tt>Object[][]</tt>. Each element in the attribute array is
79  * a two-element <tt>Object</tt> array, where <tt>Module.KEY_IDX</tt> is the attribute's
80  * key and <tt>Module.VALUE_IDX</tt> is the attribute's value.
81  * </p>
82  * <p>
83  * The actual contents of a module is contained in two sets of sources
84  * for its resources and native libraries,
85  * <a HREF="ResourceSource.html"><tt>ResourceSource</tt></a>s
86  * and <a HREF="LibrarySource.html"><tt>LibrarySource</tt></a>s, respectively.
87  * Each module also has a <a HREF="ModuleClassLoader.html"><tt>ModuleClassLoader</tt></a>
88  * associated with it. The <tt>ModuleClassLoader</tt> consults these two types
89  * of sources to find classes, resources, and native libraries.
90  * </p>
91  * @see org.ungoverned.moduleloader.ModuleManager
92  * @see org.ungoverned.moduleloader.ModuleClassLoader
93  * @see org.ungoverned.moduleloader.ResourceSource
94  * @see org.ungoverned.moduleloader.LibrarySource
95 **/

96 public class Module
97 {
98     /**
99      * This is the index used to retrieve the key of an attribute;
100      * an attribute is represented as an <tt>Object[]</tt> instance.
101     **/

102     public static final int KEY_IDX = 0;
103     /**
104      * This is the index used to retrieve the value of an attribute;
105      * an attribute is represented as an <tt>Object[]</tt> instance.
106     **/

107     public static final int VALUE_IDX = 1;
108
109     private ModuleManager m_mgr = null;
110     private String JavaDoc m_id = null;
111     private Map m_attributeMap = new HashMap();
112     private ResourceSource[] m_resSources = null;
113     private LibrarySource[] m_libSources = null;
114     private ModuleClassLoader m_loader = null;
115
116     /**
117      * <p>
118      * Constructs a <tt>Module</tt> instance that will be associated with
119      * the specified <tt>ModuleManager</tt> and will have the specified
120      * identifier, attributes, resource sources, and library sources. In general,
121      * modules should not be created directly, but should be created by making
122      * a call to <tt>ModuleManager.addModule()</tt>.
123      * </p>
124      * @param mgr the <tt>ModuleManager</tt> that will be associated to
125      * the instance.
126      * @param id the identifier of the instance.
127      * @param attributes the set of attributes associated with the instance.
128      * @param resSources the set of <tt>ResourceSource</tt>s associated with
129      * the instance.
130      * @param libSources the set of <tt>LibrarySource</tt>s associated with
131      * the instance.
132      * @see org.ungoverned.moduleloader.ModuleManager
133      * @see org.ungoverned.moduleloader.ResourceSource
134      * @see org.ungoverned.moduleloader.LibrarySource
135     **/

136     public Module(
137         ModuleManager mgr, String JavaDoc id, Object JavaDoc[][] attributes,
138         ResourceSource[] resSources, LibrarySource[] libSources)
139     {
140         m_mgr = mgr;
141         m_id = id;
142         initialize(attributes, resSources, libSources);
143     }
144
145     /**
146      * <p>
147      * Returns the identifier of the module.
148      * </p>
149      * @return the identifier of the module.
150     **/

151     public String JavaDoc getId()
152     {
153         return m_id;
154     }
155
156     /**
157      * <p>
158      * Returns the attribute set associated with this module. Attributes
159      * are represented as an array of <tt>Object</tt> arrays, i.e.,
160      * <tt>Object[][]</tt>. Each element in the attribute array is
161      * two-element <tt>Object</tt> array, where <tt>Module.KEY_IDX</tt>
162      * is the index to the attribute key and <tt>Module.VALUE_IDX</tt>
163      * is the index to the attribute value. The returned array is a
164      * copy and may be freely modified.
165      * </p>
166      * @return the attribute set associated with this module.
167     **/

168     public synchronized Object JavaDoc[][] getAttributes()
169     {
170         Set s = m_attributeMap.entrySet();
171         Object JavaDoc[][] attributes = new Object JavaDoc[s.size()][];
172         Iterator iter = s.iterator();
173         for (int i = 0; iter.hasNext(); i++)
174         {
175             Map.Entry entry = (Map.Entry) iter.next();
176             attributes[i] = new Object JavaDoc[] { entry.getKey(), entry.getValue() };
177         }
178         return attributes;
179     }
180
181     /**
182      * <p>
183      * Returns the attribute value associated with the specified key.
184      * </p>
185      * @param key the key of the attribute whose value is to be retrieved.
186      * @return the attribute's value or <tt>null</tt>.
187     **/

188     public synchronized Object JavaDoc getAttribute(String JavaDoc key)
189     {
190         return m_attributeMap.get(key);
191     }
192
193     /**
194      * <p>
195      * Sets the attribute value associated with the specified key. The
196      * attribute will be added if it does not currently exist.
197      * </p>
198      * @param key the key of the attribute whose value is to be set.
199      * @param value the new value to be associated with the attribute key.
200     **/

201     public synchronized void setAttribute(String JavaDoc key, Object JavaDoc value)
202     {
203         m_attributeMap.put(key, value);
204     }
205
206     /**
207      * <p>
208      * Returns the array of <tt>ResourceSource</tt>s associated with
209      * the module. The returned array is not a copy and therefore should
210      * not be modified.
211      * </p>
212      * @return the array of <tt>ResourceSource</tt>s associated with
213      * the module.
214      * @see org.ungoverned.moduleloader.ResourceSource
215     **/

216     public ResourceSource[] getResourceSources()
217     {
218         return m_resSources;
219     }
220
221     /**
222      * <p>
223      * Returns the array of <tt>LibrarySource</tt>s associated with
224      * the module. The returned array is not a copy and therefore should
225      * not be modified.
226      * </p>
227      * @return the array of <tt>LibrarySource</tt>s associated with
228      * the module.
229      * @see org.ungoverned.moduleloader.LibrarySource
230     **/

231     public LibrarySource[] getLibrarySources()
232     {
233         return m_libSources;
234     }
235
236     /**
237      * <p>
238      * Returns the <tt>ModuleClassLoader</tt> associated with this module.
239      * If a security manager is installed, then this method uses a privileged
240      * action to avoid a security exception being thrown to the caller.
241      * </p>
242      * @return the <tt>ModuleClassLoader</tt> associated with this module.
243      * @see org.ungoverned.moduleloader.ModuleClassLoader
244     **/

245     public synchronized ModuleClassLoader getClassLoader()
246     {
247         if (m_loader == null)
248         {
249             if (System.getSecurityManager() != null)
250             {
251                 m_loader = (ModuleClassLoader) AccessController.doPrivileged(
252                     new GetClassLoaderPrivileged(m_mgr, this));
253             }
254             else
255             {
256                 m_loader = new ModuleClassLoader(m_mgr, this);
257             }
258         }
259
260         return m_loader;
261     }
262
263     /**
264      * <p>
265      * Returns the module's identifier.
266      * </p>
267      * @return the module's identifier.
268     **/

269     public String JavaDoc toString()
270     {
271         return m_id;
272     }
273
274     /**
275      * <p>
276      * Resets the module by throwing away its associated class loader and
277      * re-initializing its attributes, resource sources, and library sources
278      * with the specified values.
279      * </p>
280      * @param attributes the new attributes to be associated with the module.
281      * @param resSources the new resource sources to be associated with the module.
282      * @param libSources the new library sources to be associated with the module.
283      * @see org.ungoverned.moduleloader.ResourceSource
284      * @see org.ungoverned.moduleloader.LibrarySource
285     **/

286     protected synchronized void reset(
287         Object JavaDoc[][] attributes, ResourceSource[] resSources,
288         LibrarySource[] libSources)
289     {
290         // Throw away class loader.
291
m_loader = null;
292         // Clear attribute map.
293
m_attributeMap.clear();
294         // Close all sources.
295
dispose();
296         // Re-initialize.
297
initialize(attributes, resSources, libSources);
298     }
299
300     /**
301      * <p>
302      * Disposes the module by closing all resource and library sources.
303      * </p>
304     **/

305     protected synchronized void dispose()
306     {
307         // Close sources.
308
for (int i = 0; (m_resSources != null) && (i < m_resSources.length); i++)
309         {
310             m_resSources[i].close();
311         }
312         for (int i = 0; (m_libSources != null) && (i < m_libSources.length); i++)
313         {
314             m_libSources[i].close();
315         }
316     }
317
318     /**
319      * <p>
320      * Initializes the module by copying the specified attribute array into
321      * a map and opening all resource and library sources.
322      * </p>
323      * @param attributes the attributes to be put into a map.
324      * @param resSources the resource sources to be opened.
325      * @param libSources the library sources to be opened.
326      * @see org.ungoverned.moduleloader.ResourceSource
327      * @see org.ungoverned.moduleloader.LibrarySource
328     **/

329     private void initialize(
330         Object JavaDoc[][] attributes, ResourceSource[] resSources, LibrarySource[] libSources)
331     {
332         for (int i = 0; (attributes != null) && (i < attributes.length); i++)
333         {
334             m_attributeMap.put(attributes[i][KEY_IDX], attributes[i][VALUE_IDX]);
335         }
336
337         m_resSources = resSources;
338         m_libSources = libSources;
339
340         // Open sources.
341
for (int i = 0; (m_resSources != null) && (i < m_resSources.length); i++)
342         {
343             m_resSources[i].open();
344         }
345         for (int i = 0; (m_libSources != null) && (i < m_libSources.length); i++)
346         {
347             m_libSources[i].open();
348         }
349     }
350
351     private static class GetClassLoaderPrivileged implements PrivilegedAction JavaDoc
352     {
353         private ModuleManager m_mgr = null;
354         private Module m_module = null;
355
356         public GetClassLoaderPrivileged(ModuleManager mgr, Module module)
357         {
358             m_mgr = mgr;
359             m_module = module;
360         }
361
362         public Object JavaDoc run()
363         {
364             return new ModuleClassLoader(m_mgr, m_module);
365         }
366     }
367 }
Popular Tags