hlship 2003/07/09 11:55:46
Modified: hivemind/xdocs localization.xml navigation.xml
hivemind/xdocs/ant ConstructRegistry.xml
hivemind/src/test/hivemind/test/ant
TestConstructRegistry.java
hivemind/src/java/org/apache/commons/hivemind/ant
ConstructRegistry.java
hivemind/src/xsl hivemind.xsl hivemind.css
hivemind/src/java/org/apache/commons/hivemind/impl
RegistryBuilder.java
Added: hivemind/xdocs ioc.xml
hivemind/src/test-data/TestConstructRegistry empty.jar
testJars.xml module.jar
Log:
Extend ConstructRegistry Ant task to read deployment descriptors from inside JARs.
Improve the registry documentation to include a master index of configurations and
services.
Revision Changes Path
1.2 +4 -3 jakarta-commons-sandbox/hivemind/xdocs/localization.xml
Index: localization.xml
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/localization.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- localization.xml 2 Jul 2003 21:41:12 -0000 1.1
+++ localization.xml 9 Jul 2003 18:55:44 -0000 1.2
@@ -61,8 +61,9 @@
<a href="apidocs/org/apache/commons/hivemind/Registry.html">Registry</a>
is created by the
<a
href="apidocs/org/apache/commons/hivemind/impl/RegistryBuilder.html">RegistryBuilder</a>,
-a locale may be specified. This is the locale for the Registry and, by extension
for all Modules.
-The locale may not be changed. By default, the JVM default locale is used.
+a locale is specified. This is the locale for the Registry and, by extension, for
all Modules
+in the registry.
+The locale may not be changed.
</p>
</section>
1.10 +1 -0 jakarta-commons-sandbox/hivemind/xdocs/navigation.xml
Index: navigation.xml
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/navigation.xml,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- navigation.xml 2 Jul 2003 21:41:12 -0000 1.9
+++ navigation.xml 9 Jul 2003 18:55:44 -0000 1.10
@@ -6,6 +6,7 @@
<item name="Services" href="/services.html"/>
<item name="Configurations" href="/configuration.html"/>
<item name="Localization" href="/localization.html"/>
+ <item name="Inversion of Control" href="/ioc.html"/>
<item name="Module Descriptor" href="/descriptor.html"/>
<item name="HiveMind Registry" href="/registry.html"/>
<item name="Ant Tasks" href="/ant/index.html" collapse="true">
1.1 jakarta-commons-sandbox/hivemind/xdocs/ioc.xml
Index: ioc.xml
===================================================================
<?xml version="1.0"?>
<!-- $Id: ioc.xml,v 1.1 2003/07/09 18:55:44 hlship Exp $ -->
<!DOCTYPE document [
<!ENTITY % common-links SYSTEM "../common/links.xml">
%common-links;
]>
<document>
<properties>
<title>Inversion of Control</title>
<author email="[EMAIL PROTECTED]">Howard M. Lewis Ship</author>
</properties>
<body>
<section name="Inversion of Control">
<p>
Seems like
<a href="http://avalon.apache.org/framework/guide-patterns-ioc.html"><b>Inversion of
Control</b></a>
is all the rage these days. The
<a href="http://avalon.apache.org/">Avalon</a> project is completely based around
it. Avalon
uses detailed assembly descriptions to tie services together ... there's no way an
Avalon component
can "look up" another component; in Avalon you explicitly connect services together.
</p>
<p>
That's the basic concept of Inversion of Control; you don't create your objects, you
describe
how they should be created. You don't connect your components and services in code,
you describe the services
required by each service your provide. The container creates the objects, wires
them together and determines
when methods are invoked.
</p>
<p>
HiveMind is much looser than Avalon. HiveMind doesn't have an explicit assembly
stage; it wires together
all the modules it can find at runtime. Service implementations may implement the
<a
href="apidocs/org/apache/commons/hivemind/InitializeService.html">InitializeService</a>
interface, which is essentially a post-creation callback; the implementation can, if
it likes, look up other
services by their well-known name.
</p>
<p>
On the other hand, HiveMind is responsible for creating services (including core
implementations
and interceptors). If you use the &set-service-ref; element to initialize your
services, you can get
something very much like Inversion of Control.
</p>
<p>
Much of the rest of Inversion of Control, the life cycle aspects, don't apply to
HiveMind services because
they are explicitly multi-threaded singletons.
They are created as needed and persist as long as the repository persists.
</p>
<p>
Purist inversion of control, as in Avalon, may be more appropriate in
well-constrained systems containing
untrusted code. HiveMind is a layer below that, not an application server, but a
microkernel. Although I can see
using HiveMind as the infrastructure of an application server, even an Avalon
application server, it doesn't
directly overlap otherwise.
</p>
</section>
</body>
</document>
1.1
jakarta-commons-sandbox/hivemind/src/test-data/TestConstructRegistry/empty.jar
<<Binary file>>
1.1
jakarta-commons-sandbox/hivemind/src/test-data/TestConstructRegistry/testJars.xml
Index: testJars.xml
===================================================================
<?xml version="1.0"?>
<registry>
<module id="org.apache.commons.hivemind" uid="1" version="1.0.0">
<description uid="2"> The master module for HiveMind. </description>
<configuration
element-type="org.apache.commons.hivemind.SymbolSourceContribution"
id="org.apache.commons.hivemind.SymbolSource" uid="3">
<description>Provides a list of sources for substitution
symbols.</description>
</configuration>
<service id="org.apache.commons.hivemind.ClassFactory"
interface="org.apache.commons.hivemind.service.ClassFactory" uid="4">
<description>Wrapper around Javassist used to dynamically
create classes such as service interceptors.</description>
<create-instance
class="org.apache.commons.hivemind.service.impl.ClassFactoryImpl"/>
</service>
<service id="org.apache.commons.hivemind.LoggingInterceptor"
interface="org.apache.commons.hivemind.ServiceInterceptorFactory"
uid="5">
<description>An interceptor factory for adding method-level
logging to a service.</description>
<create-instance
class="org.apache.commons.hivemind.service.impl.LoggingInterceptorFactory"/>
</service>
<service
id="org.apache.commons.hivemind.RemoteExceptionCoordinator"
interface="org.apache.commons.hivemind.service.RemoteExceptionCoordinator" uid="6">
<description>Used to coordinate propogation of remote
exceptions (typically, to allow cached remote data to
be discarded after a remote exception).</description>
<create-instance
class="org.apache.commons.hivemind.service.impl.RemoteExceptionCoordinatorImpl"/>
</service>
<service id="org.apache.commons.hivemind.NameLookup"
interface="org.apache.commons.hivemind.service.NameLookup"
overridable="true" required="false" uid="7">
<description> A service which can perform name lookups of
objects; typically an implementation based on JNDI is
supplied. The default implementation uses JNDI but
may be overriden for other environments, or to override
its configuration. </description>
<create-instance
class="org.apache.commons.hivemind.service.impl.NameLookupImpl"/>
</service>
<service id="org.apache.commons.hivemind.EJBProxyFactory"
interface="org.apache.commons.hivemind.ServiceImplementationFactory"
uid="8">
<description> Core service implementation factory that
constructs dynamic proxies to EJB stateless session
beans. A single parameter, the JNDI name of the proxy,
is required. </description>
<create-instance
class="org.apache.commons.hivemind.service.impl.EJBProxyFactory"/>
</service>
</module>
<module id="hivemind.test.services" uid="9" version="0.0.1">
<service id="hivemind.test.services.Simple"
interface="hivemind.test.services.SimpleService" uid="10">
<create-instance class="hivemind.test.services.impl.SimpleServiceImpl"/>
</service>
</module>
</registry>
1.1
jakarta-commons-sandbox/hivemind/src/test-data/TestConstructRegistry/module.jar
<<Binary file>>
1.3 +7 -2 jakarta-commons-sandbox/hivemind/xdocs/ant/ConstructRegistry.xml
Index: ConstructRegistry.xml
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/xdocs/ant/ConstructRegistry.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ConstructRegistry.xml 17 Jun 2003 21:13:06 -0000 1.2
+++ ConstructRegistry.xml 9 Jul 2003 18:55:44 -0000 1.3
@@ -56,9 +56,14 @@
<section name="Parameters specified as nested elements">
<subsection name="descriptors">
- <p>A path-like structure, used to identify which identifies
+ <p>A path-like structure, used to identify
which HiveMind module descriptors
(<code>hivemodule.xml</code>) should be included. </p>
+
+ <p>
+ Each path element should either be a module deployment descriptor,
+ or be a JAR containing a deployment descriptor (in the
<code>META-INF</code> folder).
+ </p>
</subsection>
</section>
1.4 +22 -1
jakarta-commons-sandbox/hivemind/src/test/hivemind/test/ant/TestConstructRegistry.java
Index: TestConstructRegistry.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/ant/TestConstructRegistry.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TestConstructRegistry.java 1 Jul 2003 11:28:53 -0000 1.3
+++ TestConstructRegistry.java 9 Jul 2003 18:55:45 -0000 1.4
@@ -188,6 +188,27 @@
assertEquals(stamp, output.lastModified());
}
+ public void testJars() throws Exception
+ {
+ ConstructRegistry cr = create();
+
+ Path p = cr.createDescriptors();
+
+ p.createPath().setLocation(new File("src/META-INF/hivemodule.xml"));
+ p.createPath().setLocation(new
File("src/test-data/TestConstructRegistry/empty.jar"));
+ p.createPath().setLocation(new
File("src/test-data/TestConstructRegistry/module.jar"));
+
+ File output = File.createTempFile("testJars-", ".xml");
+
+ output.delete();
+
+ cr.setOutput(output);
+
+ cr.execute();
+
+ compare(output, "src/test-data/TestConstructRegistry/testJars.xml");
+ }
+
protected void compare(File actual, String expectedPath) throws Exception
{
String expectedContent = readFile(new File(expectedPath));
1.3 +45 -9
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/ant/ConstructRegistry.java
Index: ConstructRegistry.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/ant/ConstructRegistry.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ConstructRegistry.java 17 Jun 2003 21:13:07 -0000 1.2
+++ ConstructRegistry.java 9 Jul 2003 18:55:45 -0000 1.3
@@ -61,12 +61,17 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import org.apache.commons.hivemind.impl.RegistryBuilder;
+import org.apache.commons.hivemind.parse.DescriptorParser;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
@@ -76,6 +81,7 @@
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
/**
* Reads some number of hivemodule deployment descriptors (specified as a fileset)
@@ -171,7 +177,10 @@
log("Reading " + f);
- Document module = builder.parse(f);
+ Document module = parse(builder, f);
+
+ if (module == null)
+ continue;
Element e = module.getDocumentElement();
@@ -190,6 +199,40 @@
}
}
+ private Document parse(DocumentBuilder builder, File file) throws SAXException,
IOException
+ {
+ if (file.getName().endsWith(".jar"))
+ return parseFromJAR(builder, file);
+
+ log("Reading deployment descriptor from " + file);
+
+ return builder.parse(file);
+ }
+
+ private Document parseFromJAR(DocumentBuilder builder, File file)
+ throws SAXException, IOException
+ {
+ JarFile jar = new JarFile(file);
+
+ ZipEntry entry = jar.getEntry(RegistryBuilder.HIVE_MODULE);
+
+ if (entry == null)
+ {
+ log(file + " does not contain a HiveMind deployment descriptor");
+ return null;
+ }
+
+ log("Reading deployment descriptor for " + file);
+
+ InputStream stream = jar.getInputStream(entry);
+
+ Document result = builder.parse(stream);
+
+ stream.close();
+
+ return result;
+ }
+
protected void writeDocument(Document document, File file) throws BuildException
{
try
@@ -211,8 +254,6 @@
protected void attachUIDs(Element module)
{
- attachUID(module);
-
NamedNodeMap attributes = module.getAttributes();
String moduleId = attributes.getNamedItem("id").getNodeValue();
@@ -253,11 +294,6 @@
node = node.getNextSibling();
}
- }
-
- protected void attachUID(Element node)
- {
-
}
protected void writeDocument(Document document, OutputStream out) throws
IOException
1.10 +35 -2 jakarta-commons-sandbox/hivemind/src/xsl/hivemind.xsl
Index: hivemind.xsl
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/xsl/hivemind.xsl,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- hivemind.xsl 2 Jul 2003 21:41:13 -0000 1.9
+++ hivemind.xsl 9 Jul 2003 18:55:45 -0000 1.10
@@ -40,6 +40,39 @@
</tbody>
</table>
+ <table class="summary">
+
+ <tr>
+ <th class="subhead">Configuration Extension
Points</th>
+ <th class="subhead">Service Extension
Points</th>
+ </tr>
+
+ <tr>
+ <td>
+
+ <xsl:for-each
select="/registry/module/configuration">
+ <xsl:sort select="@id"/>
+
+ <xsl:apply-templates
select="." mode="link"/>
+ <br/>
+ </xsl:for-each>
+
+ </td>
+
+ <td>
+
+ <xsl:for-each
select="/registry/module/service">
+ <xsl:sort select="@id"/>
+
+ <xsl:apply-templates
select="." mode="link"/>
+ <br/>
+ </xsl:for-each>
+
+ </td>
+ </tr>
+
+ </table>
+
<xsl:apply-templates select="module"/>
</body>
@@ -131,7 +164,7 @@
</xsl:for-each>
</tbody>
</table>
- <!-- TODO: TOC for the Module -->
+
<xsl:apply-templates select="configuration">
<xsl:sort select="@id"/>
</xsl:apply-templates>
1.2 +6 -0 jakarta-commons-sandbox/hivemind/src/xsl/hivemind.css
Index: hivemind.css
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/xsl/hivemind.css,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- hivemind.css 17 Jun 2003 21:13:06 -0000 1.1
+++ hivemind.css 9 Jul 2003 18:55:45 -0000 1.2
@@ -28,11 +28,17 @@
TABLE.summary TD {
border-style : dashed;
border-width : thin;
+ vertical-align: top;
}
TABLE.summary TD.description {
font-style: italic;
padding-left: 20px;
+}
+
+TABLE.summary TD
+{
+ text-align: top;
}
TABLE.summary TH.subhead
1.12 +8 -2
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/impl/RegistryBuilder.java
Index: RegistryBuilder.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/impl/RegistryBuilder.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- RegistryBuilder.java 2 Jul 2003 21:41:12 -0000 1.11
+++ RegistryBuilder.java 9 Jul 2003 18:55:46 -0000 1.12
@@ -116,6 +116,12 @@
{
private static final Log LOG = LogFactory.getLog(RegistryBuilder.class);
+ /**
+ * The path, within a JAR or the classpath, to the HiveMind module
+ * deployment descriptor: <code>META-INF/hivemodule.xml</code>.
+ */
+ public static final String HIVE_MODULE = "META-INF/hivemodule.xml";
+
/**
* List of [EMAIL PROTECTED] ModuleDescriptor}.
*/
@@ -160,7 +166,7 @@
try
{
- e = loader.getResources("META-INF/hivemodule.xml");
+ e = loader.getResources(HIVE_MODULE);
}
catch (IOException ex)
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]