Initial source commit.
git-svn-id: https://svn.apache.org/repos/asf/incubator/oscar/trunk@233031 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/org/apache/osgi/moduleloader/Module.java b/src/org/apache/osgi/moduleloader/Module.java
new file mode 100644
index 0000000..c33a5fa
--- /dev/null
+++ b/src/org/apache/osgi/moduleloader/Module.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.osgi.moduleloader;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+
+/**
+ * <p>
+ * The <tt>Module</tt> class is a grouping mechanism for application classes
+ * and resources. Conceptually, most applications are grouped into
+ * entities such as JAR files (containing classes and resources) and native
+ * libraries. In some cases, these entities are core application classes and
+ * resources, while in other cases, these entities are ancillary, such as
+ * dynamically loaded plug-ins. Applications place some level of semantics
+ * onto these types of entities or <i>modules</i>, but for the <tt>ModuleLoader</tt>,
+ * no particular semantics are attached to modules (other than they are a grouping
+ * mechanism for classes and resources). This means that the application
+ * is free to map itself into modules any way that is appropriate.
+ * </p>
+ * <p>
+ * A module has the following features:
+ * </p>
+ * <ul>
+ * <li>A unique identifier within the scope of its <tt>ModuleManager</tt>.
+ * </li>
+ * <li>A set of key-value attribute pairs.
+ * </li>
+ * <li>A set of resource sources from which it is possible to
+ * retrieve classes and resources.
+ * </li>
+ * <li>A set of native library sources from which it is possible
+ * to retrieve native libraries.
+ * </li>
+ * </ul>
+ * <p>
+ * A module's identifier must be unique within the scope of its
+ * <tt>ModuleManager</tt>, but there is no meaning associated with it. The
+ * set of attribute-value pairs attached to the module have no meaning to
+ * the <tt>ModuleManager</tt>, nor does it consult them at all. The point
+ * of these attributes is to attach meta-data for use by
+ * <a href="SearchPolicy.html"><tt>SearchPolicy</tt></a> implementations.
+ * Attributes are represented as an array of <tt>Object</tt>
+ * arrays, i.e., <tt>Object[][]</tt>. Each element in the attribute array is
+ * a two-element <tt>Object</tt> array, where <tt>Module.KEY_IDX</tt> is the attribute's
+ * key and <tt>Module.VALUE_IDX</tt> is the attribute's value.
+ * </p>
+ * <p>
+ * The actual contents of a module is contained in two sets of sources
+ * for its resources and native libraries,
+ * <a href="ResourceSource.html"><tt>ResourceSource</tt></a>s
+ * and <a href="LibrarySource.html"><tt>LibrarySource</tt></a>s, respectively.
+ * Each module also has a <a href="ModuleClassLoader.html"><tt>ModuleClassLoader</tt></a>
+ * associated with it. The <tt>ModuleClassLoader</tt> consults these two types
+ * of sources to find classes, resources, and native libraries.
+ * </p>
+ * @see org.apache.osgi.moduleloader.ModuleManager
+ * @see org.apache.osgi.moduleloader.ModuleClassLoader
+ * @see org.apache.osgi.moduleloader.ResourceSource
+ * @see org.apache.osgi.moduleloader.LibrarySource
+**/
+public class Module
+{
+ /**
+ * This is the index used to retrieve the key of an attribute;
+ * an attribute is represented as an <tt>Object[]</tt> instance.
+ **/
+ public static final int KEY_IDX = 0;
+ /**
+ * This is the index used to retrieve the value of an attribute;
+ * an attribute is represented as an <tt>Object[]</tt> instance.
+ **/
+ public static final int VALUE_IDX = 1;
+
+ private ModuleManager m_mgr = null;
+ private String m_id = null;
+ private boolean m_useParentSource = false;
+ private Map m_attributeMap = new HashMap();
+ private ResourceSource[] m_resSources = null;
+ private LibrarySource[] m_libSources = null;
+ private ModuleClassLoader m_loader = null;
+
+ /**
+ * <p>
+ * Constructs a <tt>Module</tt> instance that will be associated with
+ * the specified <tt>ModuleManager</tt> and will have the specified
+ * identifier, attributes, resource sources, and library sources. In general,
+ * modules should not be created directly, but should be created by making
+ * a call to <tt>ModuleManager.addModule()</tt>.
+ * </p>
+ * @param mgr the <tt>ModuleManager</tt> that will be associated to
+ * the instance.
+ * @param id the identifier of the instance.
+ * @param attributes the set of attributes associated with the instance.
+ * @param resSources the set of <tt>ResourceSource</tt>s associated with
+ * the instance.
+ * @param libSources the set of <tt>LibrarySource</tt>s associated with
+ * the instance.
+ * @param useParentSource a flag indicating whether or not the parent
+ * class loader should be used as a resource source; this is an
+ * ugly hack to allow a module to masquerade as the system
+ * class loader.
+ * @see org.apache.osgi.moduleloader.ModuleManager
+ * @see org.apache.osgi.moduleloader.ResourceSource
+ * @see org.apache.osgi.moduleloader.LibrarySource
+ **/
+ public Module(
+ ModuleManager mgr, String id, Object[][] attributes,
+ ResourceSource[] resSources, LibrarySource[] libSources,
+ boolean useParentSource)
+ {
+ m_mgr = mgr;
+ m_id = id;
+ m_useParentSource = useParentSource;
+ initialize(attributes, resSources, libSources);
+ }
+
+ /**
+ * <p>
+ * Returns the identifier of the module.
+ * </p>
+ * @return the identifier of the module.
+ **/
+ public String getId()
+ {
+ return m_id;
+ }
+
+ /**
+ * <p>
+ * Returns the attribute set associated with this module. Attributes
+ * are represented as an array of <tt>Object</tt> arrays, i.e.,
+ * <tt>Object[][]</tt>. Each element in the attribute array is
+ * two-element <tt>Object</tt> array, where <tt>Module.KEY_IDX</tt>
+ * is the index to the attribute key and <tt>Module.VALUE_IDX</tt>
+ * is the index to the attribute value. The returned array is a
+ * copy and may be freely modified.
+ * </p>
+ * @return the attribute set associated with this module.
+ **/
+ public synchronized Object[][] getAttributes()
+ {
+ Set s = m_attributeMap.entrySet();
+ Object[][] attributes = new Object[s.size()][];
+ Iterator iter = s.iterator();
+ for (int i = 0; iter.hasNext(); i++)
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ attributes[i] = new Object[] { entry.getKey(), entry.getValue() };
+ }
+ return attributes;
+ }
+
+ /**
+ * <p>
+ * Returns the attribute value associated with the specified key.
+ * </p>
+ * @param key the key of the attribute whose value is to be retrieved.
+ * @return the attribute's value or <tt>null</tt>.
+ **/
+ public synchronized Object getAttribute(String key)
+ {
+ return m_attributeMap.get(key);
+ }
+
+ /**
+ * <p>
+ * Sets the attribute value associated with the specified key. The
+ * attribute will be added if it does not currently exist.
+ * </p>
+ * @param key the key of the attribute whose value is to be set.
+ * @param value the new value to be associated with the attribute key.
+ **/
+ public synchronized void setAttribute(String key, Object value)
+ {
+ m_attributeMap.put(key, value);
+ }
+
+ /**
+ * <p>
+ * Returns the array of <tt>ResourceSource</tt>s associated with
+ * the module. The returned array is not a copy and therefore should
+ * not be modified.
+ * </p>
+ * @return the array of <tt>ResourceSource</tt>s associated with
+ * the module.
+ * @see org.apache.osgi.moduleloader.ResourceSource
+ **/
+ public ResourceSource[] getResourceSources()
+ {
+ return m_resSources;
+ }
+
+ /**
+ * <p>
+ * Returns the array of <tt>LibrarySource</tt>s associated with
+ * the module. The returned array is not a copy and therefore should
+ * not be modified.
+ * </p>
+ * @return the array of <tt>LibrarySource</tt>s associated with
+ * the module.
+ * @see org.apache.osgi.moduleloader.LibrarySource
+ **/
+ public LibrarySource[] getLibrarySources()
+ {
+ return m_libSources;
+ }
+
+ /**
+ * <p>
+ * Returns the <tt>ModuleClassLoader</tt> associated with this module.
+ * If a security manager is installed, then this method uses a privileged
+ * action to avoid a security exception being thrown to the caller.
+ * </p>
+ * @return the <tt>ModuleClassLoader</tt> associated with this module.
+ * @see org.apache.osgi.moduleloader.ModuleClassLoader
+ **/
+ public synchronized ModuleClassLoader getClassLoader()
+ {
+ if (m_loader == null)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ m_loader = (ModuleClassLoader) AccessController.doPrivileged(
+ new GetClassLoaderPrivileged(m_mgr, this, m_useParentSource));
+ }
+ else
+ {
+ m_loader = new ModuleClassLoader(m_mgr, this, m_useParentSource);
+ }
+ }
+
+ return m_loader;
+ }
+
+ /**
+ * <p>
+ * Returns the module's identifier.
+ * </p>
+ * @return the module's identifier.
+ **/
+ public String toString()
+ {
+ return m_id;
+ }
+
+ /**
+ * <p>
+ * Resets the module by throwing away its associated class loader and
+ * re-initializing its attributes, resource sources, and library sources
+ * with the specified values.
+ * </p>
+ * @param attributes the new attributes to be associated with the module.
+ * @param resSources the new resource sources to be associated with the module.
+ * @param libSources the new library sources to be associated with the module.
+ * @see org.apache.osgi.moduleloader.ResourceSource
+ * @see org.apache.osgi.moduleloader.LibrarySource
+ **/
+ protected synchronized void reset(
+ Object[][] attributes, ResourceSource[] resSources,
+ LibrarySource[] libSources)
+ {
+ // Throw away class loader.
+ m_loader = null;
+ // Clear attribute map.
+ m_attributeMap.clear();
+ // Close all sources.
+ dispose();
+ // Re-initialize.
+ initialize(attributes, resSources, libSources);
+ }
+
+ /**
+ * <p>
+ * Disposes the module by closing all resource and library sources.
+ * </p>
+ **/
+ protected synchronized void dispose()
+ {
+ // Close sources.
+ for (int i = 0; (m_resSources != null) && (i < m_resSources.length); i++)
+ {
+ m_resSources[i].close();
+ }
+ for (int i = 0; (m_libSources != null) && (i < m_libSources.length); i++)
+ {
+ m_libSources[i].close();
+ }
+ }
+
+ /**
+ * <p>
+ * Initializes the module by copying the specified attribute array into
+ * a map and opening all resource and library sources.
+ * </p>
+ * @param attributes the attributes to be put into a map.
+ * @param resSources the resource sources to be opened.
+ * @param libSources the library sources to be opened.
+ * @see org.apache.osgi.moduleloader.ResourceSource
+ * @see org.apache.osgi.moduleloader.LibrarySource
+ **/
+ private void initialize(
+ Object[][] attributes, ResourceSource[] resSources, LibrarySource[] libSources)
+ {
+ for (int i = 0; (attributes != null) && (i < attributes.length); i++)
+ {
+ m_attributeMap.put(attributes[i][KEY_IDX], attributes[i][VALUE_IDX]);
+ }
+
+ m_resSources = resSources;
+ m_libSources = libSources;
+
+ // Open sources.
+ for (int i = 0; (m_resSources != null) && (i < m_resSources.length); i++)
+ {
+ m_resSources[i].open();
+ }
+ for (int i = 0; (m_libSources != null) && (i < m_libSources.length); i++)
+ {
+ m_libSources[i].open();
+ }
+ }
+
+ private static class GetClassLoaderPrivileged implements PrivilegedAction
+ {
+ private ModuleManager m_mgr = null;
+ private Module m_module = null;
+ private boolean m_useParentSource = false;
+
+ public GetClassLoaderPrivileged(ModuleManager mgr, Module module, boolean useParentSource)
+ {
+ m_mgr = mgr;
+ m_module = module;
+ m_useParentSource = useParentSource;
+ }
+
+ public Object run()
+ {
+ return new ModuleClassLoader(m_mgr, m_module, m_useParentSource);
+ }
+ }
+}
\ No newline at end of file