You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by fm...@apache.org on 2005/12/21 21:18:36 UTC
svn commit: r358365 [3/4] - in
/incubator/jackrabbit/trunk/contrib/extension-framework: ./ src/ src/main/
src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/jackrabbit/
src/main/java/org/apache/jackrabbit/extension/ sr...
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/XMLNodeConfiguration.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/XMLNodeConfiguration.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/XMLNodeConfiguration.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/XMLNodeConfiguration.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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.jackrabbit.extension.configuration;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
+
+/**
+ * The <code>XMLNodeConfiguration</code> extends the Apache Commons
+ * <code>XMLConfiguration</code> by support for loading the XML configuratîon
+ * from a repository property in addition to the standard loading source such as
+ * file, URL, and streams.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date$
+ */
+public class XMLNodeConfiguration extends XMLConfiguration implements
+ RepositoryConfiguration {
+
+ /**
+ * The delegate object which takes care for actually loading and saving
+ * configuration to and from the repository.
+ */
+ private final ConfigurationIODelegate delegate =
+ new ConfigurationIODelegate(this);
+
+ {
+ // set the default encoding to UTF-8
+ setEncoding(ConfigurationIODelegate.ENCODING);
+ }
+
+ /**
+ * Creates an empty <code>XMLNodeConfiguration</code> object which can be
+ * used to synthesize a new XML file by adding values and then saving().
+ */
+ public XMLNodeConfiguration() {
+ super();
+ }
+
+ /**
+ * Creates and loads the configuration from the specified file.
+ *
+ * @param fileName The name of the XML file to load.
+ *
+ * @throws ConfigurationException Error while loading the XML file
+ */
+ public XMLNodeConfiguration(String fileName) throws ConfigurationException {
+ super(fileName);
+ }
+
+ /**
+ * Creates and loads the configuration from the specified file.
+ *
+ * @param file The XML file to load.
+ *
+ * @throws ConfigurationException Error while loading the XML file
+ */
+ public XMLNodeConfiguration(File file) throws ConfigurationException {
+ super(file);
+ }
+
+ /**
+ * Creates and loads the configuration from the specified URL
+ *
+ * @param url The location of the XML file to load.
+ *
+ * @throws ConfigurationException Error while loading the XML file
+ */
+ public XMLNodeConfiguration(URL url) throws ConfigurationException {
+ super(url);
+ }
+
+ /**
+ * Creates and loads the configuration from the specified <code>node</code>.
+ *
+ * @param node The <code>Node</code> from which to load the configuration.
+ * @throws ConfigurationException Error while loading the XML file
+ */
+ public XMLNodeConfiguration(javax.jcr.Node node)
+ throws ConfigurationException {
+ super();
+ setNode(node);
+ load();
+ }
+
+ /**
+ * Returns the <code>Node</code> on which this configuration is based. If
+ * this is not a repository-based configuration object or has not been
+ * configured to load from the repository, this method returns
+ * <code>null</code>.
+ */
+ public javax.jcr.Node getNode() {
+ return delegate.getNode();
+ }
+
+ /**
+ * Sets the <code>Node</code> on which this configuration is based.
+ */
+ public void setNode(javax.jcr.Node node) {
+ delegate.setNode(node);
+ }
+
+ /**
+ * Loads the configuration from the underlying location.
+ *
+ * @throws ConfigurationException if loading of the configuration fails
+ */
+ public void load() throws ConfigurationException {
+ delegate.load();
+ }
+
+ /**
+ * Loads the configuration from the <code>node</code>. The property to
+ * use is found following the the node's primary item trail: While the
+ * primary item is a node, the node's primary item is accessed. If it is a
+ * property which is not a reference, the property is returned. If the
+ * property is a reference, the reference is resolved and this step is
+ * repeated.
+ * <p>
+ * If no property can be found using above mentioned algorithm, loading the
+ * configuration fails.
+ *
+ * @param node The <code>Node</code> of the repository based configuration
+ * to load from.
+ * @throws ConfigurationException if an error occurs during the load
+ * operation or if no property can be found containing the
+ * properties "file".
+ */
+ public void load(javax.jcr.Node node) throws ConfigurationException {
+ delegate.load(node);
+ }
+
+ /**
+ * Saves the configuration to the underlying location.
+ *
+ * @throws ConfigurationException if saving of the configuration fails
+ */
+ public void save() throws ConfigurationException {
+ delegate.save();
+ }
+
+ /**
+ * Saves the configuration in the <code>node</code>. The same algorithm
+ * applies for finding the property to store the configuration in as is
+ * applied by the {@link #load(javax.jcr.Node)} method. If no property can
+ * be found saving the configuration fails.
+ *
+ * @param node The <code>Node</code> of the repository based configuration
+ * to save the configuration in.
+ *
+ * @throws ConfigurationException if an error occurs during the save
+ * operation.
+ */
+ public void save(javax.jcr.Node node) throws ConfigurationException {
+ delegate.save(node);
+ }
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/XMLNodeConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/XMLNodeConfiguration.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/package.html
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/package.html?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/package.html (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/package.html Wed Dec 21 12:17:51 2005
@@ -0,0 +1,8 @@
+<body>
+<p>
+This package contains classes and interfaces extending the Jakarta Commons
+Configuration library by support for Repository based configuration where
+the nodes and properties are read from and written to a subtree of the
+repository.
+</p>
+</body>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/package.html
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/package.html?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/package.html (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/package.html Wed Dec 21 12:17:51 2005
@@ -0,0 +1,4 @@
+<body>
+<p>This package contains the Jackrabbit Extension Framework. See the Jackrabbit
+Extension Framework site for an in-depth description.</p>
+</body>
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd Wed Dec 21 12:17:51 2005
@@ -0,0 +1,30 @@
+/*
+ * The "type.cnd" file contains the (mixin) node type definition which is
+ * required by the ExtensionManager class.
+ *
+ * NOTE: This file is read through a reader with encoding "ISO-8859-1".
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date:$
+ * @see org.apache.jackrabbit.extension.ExtensionManager
+ * @see org.apache.jackrabbit.extension.NodeTypeSupport
+ */
+
+// The "rep" namespace is expected to be present in the repository.
+// For Jackrabbit based repositories, this is true, for other repositories, we
+// present the namespace declaration here.
+// This declaration is inline with the Jackrabbit internal namespace declaration
+// for the "rep" namespace.
+<rep = 'internal'>
+<nt = 'http://www.jcp.org/jcr/nt/1.0'>
+
+[rep:extension] mixin
+
+- rep:name(string) mandatory copy
+- rep:id(string) mandatory copy
+- rep:class(string) copy
+- rep:classpath(path) multiple copy
+- rep:configurationClass(string) copy
+
++ rep:configuration (nt:base) = nt:unstructured
+ multiple copy
\ No newline at end of file
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd.bak
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd.bak?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd.bak (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd.bak Wed Dec 21 12:17:51 2005
@@ -0,0 +1,38 @@
+/*
+ * The "type.cnd" file contains the (mixin) node type definition which is
+ * required by the ExtensionManager class.
+ *
+ * NOTE: This file is read through a reader with encoding "ISO-8859-1".
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date:$
+ * @see org.apache.jackrabbit.extension.ExtensionManager
+ * @see org.apache.jackrabbit.extension.NodeTypeSupport
+ */
+
+// The "rep" namespace is expected to be present in the repository.
+// For Jackrabbit based repositories, this is true, for other repositories, we
+// present the namespace declaration here.
+// This declaration is inline with the Jackrabbit internal namespace declaration
+// for the "rep" namespace.
+<rep = 'internal'>
+<nt = 'http://www.jcp.org/jcr/nt/1.0'>
+
+[rep:extension] mixin
+
+- rep:name(string) mandatory copy
+- rep:id(string) mandatory copy
+- rep:class(string) copy
+- rep:classpath(path) mandatory multiple copy
+- rep:name(string) mandatory copy
+- rep:name(string) mandatory copy
+
+// The "rep:jarContents" is the root node of the subtree into which the archive
+// is unpacked. There is no explicit type requirement for the type of this
+// node, except, that it must be allowed nodes of type "nt:file" and "nt:folder"
+// below. Unpacking the archive in the ExpandingArchiveClassPathEntry class
+// will create the "rep:jarContents" node as an nt:folder node and create files
+// and folders contained in the archive as "nt:file" and "nt:folder" nodes,
+// respectively.
++ rep:jarContents (nt:base) = nt:folder
+ mandatory copy
\ No newline at end of file
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/classes.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/classes.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/classes.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/classes.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,115 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framework - Extension Classes</title>
+ </properties>
+ <body>
+ <section name="Extension Classes">
+ <p>
+ The extension declaration may also contain the (fully
+ qualified) name of a class implementing the extension.
+ Besides finding extension descriptions the Jackrabbit Extension
+ Framework is also able to create instances of extensions
+ and prime them with the extension descriptor, which
+ defined how to instantiate the extension.
+ </p>
+ <p>
+ This page contains information on how class implementing
+ the extensions are loaded how the extensions are then
+ instantiated.
+ </p>
+
+ <subsection name="Loading">
+ <p>
+ All access to the Jackrabbit Extensions Framework goes
+ through an instance of the
+ <code>ExtensionManager</code>
+ class, which is created using a
+ <code>Session</code>
+ and a class loader. While the session is used to
+ access the repository and also confines access to a
+ certain workspace, the class loader provided is
+ actually the basis for loading extension classes.
+ </p>
+ <p>
+ As has been noted in the
+ <a href="index.html#Introduction">Introduction</a>
+ one of the advantages of the Jackrabbit Extension Framework
+ is its ability to load extension classes from the
+ repository, an extension may be packaged complete
+ with the descriptor, optional configuration and the
+ Java classes and/or archives implementing the
+ extensions. To be able to load the classes from the
+ repository, the Jackrabbit Extension Framework uses
+ instances of the <code>RepositoryClassLoader</code>
+ provided by the <code>classloader</code> project.
+ </p>
+ <p>
+ The extension manager creates a separate instance of
+ the
+ <code>RepositoryClassLoader</code>
+ for each extension type accessed. The class path
+ defined by an extension is added to that class
+ loader before trying to load the class through that
+ class loader. The class loader created by the
+ extension manager is linked into the system class
+ loader hierarchy by using the application provided
+ class loader given to the constructor of the
+ extension manager as its parent class loader.
+ </p>
+ <p>
+ Please be aware of an issue raising from the fact
+ that class may be loaded through a class loader
+ which is a child of the application's class loader:
+ While extensions have access to all the classes
+ provided by the repository class loader as well as
+ the application class loader and all its parents,
+ the application has no access to the classes loaded
+ through the repository class loader. This is easily
+ fixed by having the extensions implement interfaces
+ which are loaded through the application class
+ loader and to which the extension instances loaded
+ through the extension manager may be cast.
+ </p>
+ </subsection>
+
+ <subsection name="Instantiation">
+ <p>
+ The extension declaration may also contain the
+ (fully qualified) name of a class implementing the
+ extension. If so, the Jackrabbit Extension Framework
+ provides support functionality to load and
+ instantiate the respective class using either of two
+ constructors:
+ </p>
+ <ul>
+ <li>
+ If the class has a (public) constructor taking
+ an object of type
+ <code>
+ org.apache.jackrabbit.extension.ExtensionDescriptor
+ </code>
+ this constructor is used to instanti-ate the
+ extension instance.
+ </li>
+ <li>
+ Otherwise if the class has a (public) default
+ constructor this constructor is used to
+ in-stantiated the extension interface.
+ </li>
+ <li>
+ Otherwise the extension cannot be instantiated.
+ </li>
+ </ul>
+ <p>
+ If the extension cannot be instantiated through the
+ constructor taking the
+ <code>ExtensionDescriptor</code>
+ the application is responsible to provide the
+ relevant information to the extension instance if
+ required.
+ </p>
+ </subsection>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/classes.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/configuration.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/configuration.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/configuration.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/configuration.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,162 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framework - Configuration</title>
+ </properties>
+ <body>
+ <section name="Configuration">
+ <p>
+ The Jackrabbit Extension framework supports configuration of
+ the extensions by means of the
+ <a
+ href="http://jakarta.apache.org/commons/configuration/">
+ Apache Commons Configuration
+ </a>
+ project. As such, the class specified in the
+ <code>rep:configurationClass</code>
+ property of the extension descriptor must implement the
+ <code>Configuration</code>
+ interface. Generally, it will be an implementation of
+ the
+ <code>RepositoryConfiguration</code>
+ interface, which supports loading and saving of
+ configuration from and to the Jackrabbit repository. The Jackrabbit
+ Extension Framework provides three implementations of
+ the
+ <code>RepositoryConfiguration</code>
+ interface:
+ <code><a href="#ItemConfiguration">ItemConfiguration</a></code>,
+ <code><a href="#PropertiesNodeConfiguration">PropertiesNodeConfiguration</a></code>
+ and
+ <code><a href="#XMLNodeConfiguration">XMLNodeConfiguration</a></code>.
+ </p>
+ <p>
+ The default configuration class used if none is
+ configured in the extension node, is the
+ <code>ItemConfiguration</code>.
+ </p>
+ <p>
+ The configuration object is only created and loaded when
+ the
+ <code>getConfiguration()</code>
+ method of the extension descriptor is first called.
+ </p>
+
+ <subsection name="ItemConfiguration">
+ <p>
+ The
+ <code>
+ <a
+ href="apidocs/org/apache/jackrabbit/extension/configuration/ItemConfiguration.html">
+ ItemConfiguration
+ </a>
+ </code>
+ loads a subtree of the repository rooted at the
+ <code>rep:configuration</code>
+ child node of the extension node as a
+ <code>
+ <a
+ href="http://jakarta.apache.org/commons/configuration/apidocs/org/apache/commons/configuration/HierarchicalConfiguration.html">
+ HierarchicalConfiguration</a></code>. Each node
+ in the subtree becomes a configuration
+ node and each property becomes an attribute.
+ Protected nodes and properties (such as
+ <i>jcr:primaryType</i>) are ignored and neither read nor
+ written (they cannot be written anyway).
+ </p>
+ <p>
+ Generally the nodes making up the
+ <code>ItemConfiguration</code>
+ will be
+ <code>nt:unstructured</code>
+ node thus providing full flexibility for defining
+ the configuration. When an instance of the
+ <code>ItemConfiguration</code>
+ class saves configuration data, this node type is
+ used for newly created nodes.
+ </p>
+ <p>
+ <b>Example</b>
+ </p>
+ <source><![CDATA[
+/extensions/sample
+ +-- ... extension descriptor omitted ...
+ +-- rep:configuration
+ +-- handler
+ | +-- class = "some.Class"
+ | +-- name = "the name"
+ | +-- path = [ "/folder1", "/folder2" ]
+ +-- codes
+ +-- boolean = true
+ +-- double = 2.5D
+ +-- long = 10L
+ +-- string = "a string"
+ +-- date = 2002-10-11Z19:28]]></source>
+ <p>
+ The data structure shown above translates into a
+ configuration data structure with the following
+ contents. Note the
+ <i><b>[@</b>name<b>]</b></i>
+ notation which designates configuration attributes
+ in contrast to configuration nodes.
+ </p>
+ <source><![CDATA[
+handler[@class] = "some.Class"
+handler[@name] = "the name"
+handler[@path](0) = "/folder1"
+handler[@path](1) = "/folder2"
+handler.codes[@boolean] = true
+handler.codes[@double] = 2.5D
+handler.codes[@long] = 10L
+handler.codes[@string] = "a string"
+handler.codes[@date] = 2002-10-11Z19:28]]></source>
+ </subsection>
+
+ <subsection name="PropertiesNodeConfiguration">
+ <p>
+ The
+ <code>
+ <a
+ href="apidocs/org/apache/jackrabbit/extension/configuration/PropertiesNodeConfiguration.html">
+ PropertiesNodeConfiguration
+ </a>
+ </code>
+ extends the
+ <code>
+ <a
+ href="http://jakarta.apache.org/commons/configuration/apidocs/org/apache/commons/configuration/PropertiesConfiguration.html">
+ PropertiesConfiguration
+ </a>
+ </code>
+ class and supports loading and saving of properties
+ files from and to the
+ <code>rep:configuration</code>
+ property of the extension node.
+ </p>
+ </subsection>
+
+ <subsection name="XMLNodeConfiguration">
+ <p>
+ The
+ <code>
+ <a
+ href="apidocs/org/apache/jackrabbit/extension/configuration/XMLNodeConfiguration.html">
+ XMLNodeConfiguration
+ </a>
+ </code>
+ extends the
+ <code>
+ <a
+ href="http://jakarta.apache.org/commons/configuration/apidocs/org/apache/commons/configuration/XMLConfiguration.html">
+ XMLConfiguration
+ </a>
+ </code>
+ class and supports loading and saving of XML files
+ from and to the
+ <code>rep:configuration</code>
+ property of the extension node.
+ </p>
+ </subsection>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/configuration.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framework - Examples</title>
+ </properties>
+ <body>
+ <section name="Examples">
+ <p>Examples provided in this section:</p>
+ <dl>
+ <dt>
+ <a href="examples/listing.html">
+ Listing Extensions
+ </a>
+ </dt>
+ <dd>Shows how to list extensions of a given type.</dd>
+ <dt>
+ <a href="examples/instantiating.html">
+ Creating Extension Instances
+ </a>
+ </dt>
+ <dd>
+ Shows how to instantiate extensions of a given type.
+ </dd>
+ <dt>
+ <a href="examples/deployment.html">Deployment</a>
+ </dt>
+ <dd>
+ Shows a way to deploy an extensions complete with
+ its descriptor, the classes implementing the
+ extension and required configuration.
+ </dd>
+ </dl>
+
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/deployment.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/deployment.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/deployment.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/deployment.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framework - Deployment</title>
+ </properties>
+ <body>
+ <section name="Deployment">
+ <p>
+ This sample shows how an extension may be provided in
+ the repository for easy use by the Jackrabbit Extension
+ Framework.
+ </p>
+
+ <source><![CDATA[/extensions/sample -- node of type nt:folder, rep:extension
+ +-- rep:id = "org.apache.jackrabbit.sample"
+ +-- rep:name = "Sample1"
+ +-- rep:class = "org.apache.jackrabbit.sample.Sample1"
+ +-- rep:classpath = [ /extension/sample/sample.jar ]
+ +-- sample.jar -- node of type nt:file containing the JAR file
+ +-- rep:configuration -- node of type nt:file containing the configuration
+ +-- jcr:content
+ +-- jcr:data -- XML configuration file data]]></source>
+
+ <p>
+ When this extension is loaded, the
+ <code>sample.jar</code>
+ is added to the class loader of the
+ <i>org.apache.jackrabbit.sample</i>
+ extension type and the class
+ <code>org.apache.jackrabbit.sample.Sample1</code>
+ is loaded through that class loader. If the class
+ provides a public constructor taking an instance of
+ <code>ExtensionDescriptor</code>
+ the extension class may access the descriptor's node to
+ get at the configuration stored in the
+ <code>config</code>
+ child node. If the class provides a public setter method
+ for a field of type <code>ExtensionDescriptor</code>, that
+ method is called to set the descriptor.
+ </p>
+ <p>
+ This extension may easily be packaged, distributed and
+ deployed without requiring to hassle around with Jackrabbit
+ runtime configuration.
+ </p>
+
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/deployment.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/instantiating.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/instantiating.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/instantiating.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/instantiating.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framework - Creating Extension Instances</title>
+ </properties>
+ <body>
+ <section name="Creating Extension Instances">
+ <source><![CDATA[// get the session
+Session session = ....;
+
+// get the application class loader
+ClassLoader loader = Sample1.class.getClassLoader();
+
+// get the extension manager
+ExtensionManager mgr = new ExtensionManager(session, loader);
+
+// get iterator for extensions
+Iterator extensions = mgr.findExtensions("org.apache.jackrabbit.sample", null);
+while (extensions.hasNext()) {
+ ExtensionDescriptor desc = (ExtensionDescriptor) extensions.next();
+
+ Object extension = desc.getExtension();
+
+ // handle extension
+}
+
+// dispose of session
+session.logout();]]></source>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/instantiating.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/listing.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/listing.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/listing.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/listing.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framework - Listing Extensions</title>
+ </properties>
+ <body>
+ <section name="Listing Extensions">
+ <source><![CDATA[// get the session
+Session session = ....;
+
+// get the application class loader
+ClassLoader loader = Sample1.class.getClassLoader();
+
+// get the extension manager
+ExtensionManager mgr = new ExtensionManager(session, loader);
+
+// get iterator for extensions
+Iterator extensions = mgr.findExtensions("org.apache.jackrabbit.sample", null);
+while (extensions.hasNext()) {
+ ExtensionDescriptor desc = (ExtensionDescriptor) extensions.next();
+
+ System.out.println("Extension: ");
+ System.out.println(" Type ID......: " + desc.getId());
+ System.out.println(" Name.........: " + desc.getName());
+
+ System.out.print (" Class........: ");
+ if (desc.getClassName() == null) {
+ System.out.println("-");
+ } else {
+ System.out.println(desc.getClassName());
+ }
+
+ System.out.print (" Class Path...: ");
+ if (desc.getClassPath() == null) {
+ System.out.println("-");
+ } else {
+ for (int i=0; i < desc.getClassPath().length; i++) {
+ System.out.print((i==0) ? '[' : ',');
+ System.out.print(desc.getClassPath()[i]);
+ }
+ System.out.println("]");
+ }
+}
+
+// dispose of session
+session.logout();]]></source>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/listing.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/index.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/index.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/index.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/index.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framwork - Overview</title>
+ </properties>
+ <body>
+ <section name="Introduction">
+ <p>
+ Jackrabbit, the Apache Group's open source implementation
+ of the Content Repository for Java Technology API (JSR
+ 170), will be the basis for a series of upcoming
+ products. Some are more integrated with Jackrabbit, like
+ the WebDAV server, some are plain applications of the Jakrabbit,
+ like for example a repository based content management system.
+ </p>
+
+ <p>All of these applications share similar requirements:</p>
+
+ <ul>
+ <li>Extensibility of some sort</li>
+ <li>Configuration requirements</li>
+ </ul>
+
+ <p>
+ To address these common problems and to provide an easy
+ to use framework to jump start on this extensibility
+ issue without requiring tedious configuration steps at
+ different locations, this document proposes the Jackrabbit
+ Extension Framework.
+ </p>
+
+ <p>
+ The core of the Jackrabbit Extension Framework is the
+ <code>
+ <a
+ href="apidocs/org/apache/jackrabbit/extension/ExtensionManager.html">
+ org.apache.jackrabbit.extension.ExtensionManager
+ </a>
+ </code>
+ which provides the API to load and instantiate
+ extensions for further use. The basic concepts of
+ extensions are as follows:
+ </p>
+
+ <ul>
+ <li>
+ An extension is part of a group ofextensions sharing
+ common functionality. Each such group is called an
+ extension type and has a name. That name, commonly
+ called the <i>extension type identification</i>, should
+ be unique within a single application.
+ There is no additional semantic bound to an
+ extension type identification. In fact the
+ uniqueness requirement is not enforced and it is the
+ sole responsibility of the administrator and/or
+ extension type implementor to make sure there are no
+ two extension types with the same identification. A
+ simple method to handle this issue is to apply the
+ same naming conventions as proposed by Sun for
+ <a
+ href="http://java.sun.com/docs/codeconv/html/CodeConventions.doc8.html#367">
+ package names
+ </a>
+ .
+ </li>
+ <li>
+ Each extension has a unique name within the realm of
+ its extension type. Again, this requirement is not
+ enforced and it is the administrator's or
+ implementor's responsibility to guarantee this
+ uniqueness requirement.
+ </li>
+ <li>
+ An extension may be implemented by some Java code,
+ which should be loaded into the system for use. That
+ is, an extension has an associated class and
+ optionally a class path to indicated where to load
+ the Java classes from. To simplify deployment of
+ extensions the classes (or JAR archives) containing
+ the extension implementation together with optional
+ required libraries may be stored in the repository.
+ </li>
+ <li>
+ Often times extensions need to be provided with some
+ sort of configuration, which of course would also be
+ stored in the repository.
+ </li>
+ </ul>
+
+ <p>
+ As a consequence of the above noted uniques requirements
+ for extension type identifications and extension names,
+ two instances of the
+ <code>
+ <a
+ href="apidocs/org/apache/jackrabbit/extension/ExtensionDescriptor.html">
+ ExtensionDescriptor
+ </a>
+ </code>
+ class are considered equal if the have the same type
+ identification and name.
+ </p>
+
+ <p>
+ See
+ <a href="examples/deployment.html">Deployment</a>
+ for a sample extension stored in the repository.
+ </p>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/index.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/misc.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/misc.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/misc.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/misc.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framework - Loose Ends</title>
+ </properties>
+ <body>
+ <section name="Dependencies">
+ <p>
+ The Jackrabbit Extension Framework itself has no provision of
+ defining dependencies amongst extensions of a certain
+ type. This has to be implemented in the application of
+ the extension framework.
+ </p>
+ <p>
+ Some examples of how this might be accomplished follow.
+ </p>
+ <subsection name="Priorities">
+ <p>
+ If the extensions define sort of a operations chain,
+ a priority may be specified which defines the order
+ in which the operations are executed. The priority
+ may be stored in the extension node as an additional
+ property, which is read by the extension
+ constructor.
+ </p>
+ </subsection>
+ <subsection name="Dependencies">
+ <p>
+ If the extensions define services provided which may
+ have dependencies amongst each other, the respective
+ dependencies may be stored in an additional property
+ in the descriptor node, which is read by the
+ extension constructor. Before actually activating
+ the services, the dependencies may be handled by the
+ application to define an activation order.
+ </p>
+ </subsection>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/misc.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/navigation.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/navigation.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/navigation.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/navigation.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project>
+ <title>Jackrabbit Extension Framework</title>
+ <body>
+ <menu name="Jackrabbit Extension Framework">
+ <item name="Overview" href="/index.html">
+ <item name="Extension Node Type" href="/nodetype.html" />
+ <item name="Extension Classes" href="/classes.html" />
+ <item name="Configuration" href="/configuration.html" />
+ <item name="Loose Ends" href="/misc.html" />
+ </item>
+ <item name="Examples" href="/examples.html">
+ <item name="Listing Extensions" href="/examples/listing.html" />
+ <item name="Creating Extension Instances" href="/examples/instantiating.html" />
+ <item name="Deployment" href="/examples/deployment.html" />
+ </item>
+ </menu>
+ </body>
+</project>
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/navigation.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/nodetype.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/nodetype.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/nodetype.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/nodetype.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,117 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+ <title>Jackrabbit Extension Framwork - Node Types</title>
+ </properties>
+ <body>
+ <section name="Node Type Definition">
+ <p>
+ A Jackrabbit extension is represented as a node in the
+ repository at an application defined location with mixin
+ node type
+ <code>rep:extension</code>
+ which is defined in compact node type definition format
+ as follows:
+ </p>
+
+ <source><![CDATA[[rep:extension] mixin
+ - rep:name (string) mandatory copy
+ - rep:id (string) mandatory copy
+ - rep:class (string) copy
+ - rep:classpath (path) multiple copy
+ - rep:configurationClass (string) copy
+ + rep:configuration (nt:base) = nt:unstructured multiple copy]]></source>
+
+ <p>
+ The
+ <code>rep:extension</code>
+ type is a mixin node type and as such any node may be
+ designated as the declaring node of an extension. The
+ advantage of this is that the extension declaring node
+ may at the same time be the root node of the extension
+ configuration also read from the repository.
+ </p>
+ <p>
+ The
+ <code>rep:id</code>
+ property contains the name of the extension type
+ provided by this extension. It is recommended that
+ extension type names follow the same pattern of reversed
+ domain name prefixes as is specified for Java packages.
+ </p>
+ <p>
+ The
+ <code>rep:name</code>
+ property contains the name of the extension itself. This
+ name identifies the concrete definitions amongst the set
+ of extensions defined with the same extension type. The
+ name of the extension must be unique amongst all
+ extensions of the same type.
+ </p>
+ <p>
+ The
+ <code>rep:class</code>
+ property contains the fully qualified name of the class
+ implementing this extensions. If this property is not
+ empty, the Jackrabbit Extension Framework is able to provide
+ instantiation support for that class. Refer to the
+ section
+ <a href="classes.html">Extension Classes</a>
+ for explanations of class loading support in the Jackrabbit
+ Extension Framework.
+ </p>
+ <p>
+ The multivalued
+ <code>rep:classpath</code>
+ property contains a list of absolute repository path
+ names denoting the classpath used to load the extension.
+ </p>
+ <p>
+ The
+ <code>rep:configurationClass</code>
+ property contains the fully qualified name of the class,
+ which is used to provide configuration to the extension.
+ The class must implement the
+ <code>
+ <a
+ href="http://jakarta.apache.org/commons/configuration/apidocs/org/apache/commons/configuration/Configuration.html">
+ org.apache.commons.configuration.Configuration
+ </a>
+ </code>
+ interface. If missing the configuration is loaded
+ through an
+ <code>
+ <a
+ href="apidocs/org/apache/jackrabbit/extension/configuration/ItemConfiguration.html">
+ ItemConfiguration
+ </a>
+ </code>
+ instance. Refer to the section
+ <a href="configuration.html">Configuration</a>
+ for more information on configuration support of the Jackrabbit
+ Extension Framework.
+ </p>
+ <p>
+ The <code>rep:configuration</code> child node contains the
+ extensions configuration. The
+ <a href="apidocs/org/apache/jackrabbit/extension/ExtensionDescriptor.html#getConfigurationNode()">ExtensionDescriptor.getConfigurationNode</a>
+ method returns this node and the
+ <a href="apidocs/org/apache/jackrabbit/extension/ExtensionDescriptor.html#getConfiguration()">ExtensionDescriptor.getConfiguration</a>
+ method will load the configuration from this node. This node
+ may be of any type. For example it may be a <code>nt:file</code>
+ node whose <code>jcr:content/jcr:data</code> property contains
+ the XML configuration file.
+ </p>
+ <p>
+ The
+ <code>ExtensionManager</code>
+ class loads extensions defined with this node type
+ through its
+ <code>findExtensions</code>
+ method loading the content into instances of the
+ <code>ExtensionDescriptor</code>
+ class for ease of access.
+ </p>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/nodetype.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFindTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFindTest.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFindTest.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFindTest.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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.jackrabbit.extension;
+
+import java.util.Iterator;
+
+import org.apache.commons.configuration.Configuration;
+
+public class ExtensionFindTest extends ExtensionFrameworkTestBase {
+
+ protected ExtensionManager em;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ ExtensionManager.checkNodeType(session);
+ fillTestData(session);
+ em = new ExtensionManager(session, getClass().getClassLoader());
+ }
+
+ protected void tearDown() throws Exception {
+ em = null;
+ removeTestData(session);
+ super.tearDown();
+ }
+
+ public void testFindings() throws ExtensionException {
+
+ Iterator ei = em.getExtensions(ID1, ROOT_NODE);
+ while (ei.hasNext()) {
+ ExtensionDescriptor ed = (ExtensionDescriptor) ei.next();
+ System.out.println("Extension " + ed.getId() + "/" + ed.getName() + " (" + ed.getNodePath() +")");
+
+ if (ed.getClassName() != null) {
+ Object ext = ed.getExtension();
+ System.out.println(" Class : " + ed.getClassName());
+ System.out.println(" ClassLoader : " + ext.getClass().getClassLoader());
+ System.out.println(" Extension : " + ext);
+ }
+
+ Configuration config = ed.getConfiguration();
+ System.out.println(" Configuration Class : " + config.getClass().getName());
+ System.out.println(" Configuration : " + config);
+ for (Iterator ki=config.getKeys(); ki.hasNext(); ) {
+ String key = (String) ki.next();
+ Object prop = config.getProperty(key);
+ System.out.println(" " + key + " ==> " + prop);
+ }
+ }
+ }
+
+ public void testFindNonExisting() {
+ try {
+ em.getExtension(ID1, "google", ROOT_NODE);
+ } catch (ExtensionException ee) {
+ assertTrue("Wrong exception " + ee + " thrown",
+ ee.getMessage() != null &&
+ ee.getMessage().indexOf("not found") > 0);
+ }
+ }
+
+ public void testFindExisting() throws ExtensionException {
+ em.getExtension(ID1, "delivery.core", ROOT_NODE);
+ }
+
+ public void testFindMultipleExisting() {
+ try {
+ em.getExtension(ID1, "delivery.gfx", ROOT_NODE);
+ } catch (ExtensionException ee) {
+ assertTrue("Wrong exception " + ee + " thrown",
+ ee.getMessage() != null &&
+ ee.getMessage().indexOf("ore than one extension") > 0);
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFindTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFindTest.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFrameworkTestBase.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFrameworkTestBase.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFrameworkTestBase.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFrameworkTestBase.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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.jackrabbit.extension;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory;
+
+/**
+ * The <code>ExtensionFrameworkTestBase</code> TODO
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date$
+ */
+public class ExtensionFrameworkTestBase extends TestCase {
+
+ /** Logger for test cases */
+ protected static final Log log =
+ LogFactory.getLog("org.apache.jackrabbit.extension.test");
+
+ protected static final String WORKSPACE = "default";
+ protected static final String USER = "admin";
+
+ protected static final String PROVIDER_URL = "ClassLoader";
+ protected static final String REPOSITORY_NAME = "ClassLoaderRepository";
+
+ protected static final String ROOT_NODE = "/services";
+ protected static final String ID1 = "org.apache.jackrabbit.app.services";
+ protected static final String ID2 = "org.apache.jackrabbit.test";
+
+ protected RepositoryImpl repository;
+ protected Session session;
+
+ public ExtensionFrameworkTestBase() {
+ super();
+ }
+
+ public ExtensionFrameworkTestBase(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ if (!"repositoryStart".equals(getName())) {
+ Context ctx = getInitialContext();
+ repository = (RepositoryImpl) ctx.lookup(REPOSITORY_NAME);
+
+ Credentials creds = new SimpleCredentials(USER, USER.toCharArray());
+ session = repository.login(creds, WORKSPACE);
+ }
+ }
+
+ public void repositoryStart() throws Exception {
+ InputStream config = getClass().getResourceAsStream("/repository.xml");
+ String home = new File("cltest").getAbsolutePath();
+ RepositoryConfig rc = RepositoryConfig.create(config, home);
+ RepositoryImpl repository = RepositoryImpl.create(rc);
+
+ try {
+ Context ctx = getInitialContext();
+ ctx.bind(REPOSITORY_NAME, repository);
+ } catch (NamingException ne) {
+ repository.shutdown();
+ throw ne;
+ }
+ }
+
+ public void repositoryStop() throws Exception {
+ // this is special, logout here and clean repository
+ disconnect();
+ if (repository != null) {
+ repository.shutdown();
+ repository = null;
+ }
+
+ Context ctx = getInitialContext();
+ ctx.unbind(REPOSITORY_NAME);
+ }
+
+ protected void tearDown() throws Exception {
+ disconnect();
+ repository = null;
+ super.tearDown();
+ }
+
+ private Context getInitialContext() throws NamingException {
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ DummyInitialContextFactory.class.getName());
+ env.put(Context.PROVIDER_URL, PROVIDER_URL);
+
+ return new InitialContext(env);
+ }
+
+ private void disconnect() {
+ if (session != null) {
+ try {
+ removeTestData(session);
+ } catch (RepositoryException re) {
+ // ignore
+ }
+ session.logout();
+ session = null;
+ }
+ }
+
+ //---------- RepositoryLoader ----------------------------------------------
+
+ protected void fillTestData(Session session) throws RepositoryException {
+ try {
+ session.getItem(ROOT_NODE).remove();
+ session.save();
+ } catch (PathNotFoundException ignore) {
+ // ok, if root no extisting
+ }
+
+ // make sure the root is available
+ ensurePath(session, ROOT_NODE);
+
+ fillExtension(session, ROOT_NODE+"/delivery/core", ID1, "delivery.core", null, null, null);
+ fillExtension(session, ROOT_NODE+"/delivery/cache", ID1, "delivery.cache", null, null, null);
+ fillExtension(session, ROOT_NODE+"/delivery/link", ID1, "delivery.link", null, null, null);
+ fillExtension(session, ROOT_NODE+"/delivery/script", ID1, "delivery.script", null, null, null);
+ fillExtension(session, ROOT_NODE+"/delivery/gfx", ID1, "delivery.gfx", null, null, null);
+
+ fillExtension(session, ROOT_NODE+"/development/jsp", ID1, "development.jsp", null, null,
+ "org.apache.jackrabbit.extension.configuration.ItemConfiguration");
+ fillExtension(session, ROOT_NODE+"/development/ecma", ID1, "development.ecma", null, null, null);
+
+ String devCore = ROOT_NODE + "/development/core";
+ fillExtension(session, devCore, ID1, "development.core",
+ "org.apache.jackrabbit.extension.DevCoreTest", devCore+"/classes", null);
+ putClass(session, devCore, "DevCoreTest.class");
+
+ // duplicate extension - ok for iterator, not ok for explicit finding
+ fillExtension(session, ROOT_NODE+"/delivery/gfx2", ID1, "delivery.gfx", null, null, null);
+ }
+
+ protected static void removeTestData(Session session) throws RepositoryException {
+ session.getItem(ROOT_NODE).remove();
+ session.save();
+ }
+
+ private static void fillExtension(Session session, String path, String id,
+ String name, String clazz, String classPath, String configClass)
+ throws RepositoryException {
+
+ // get the extension's node
+ Node extNode = ensurePath(session, path);
+
+ // mark as an extension
+ extNode.addMixin(ExtensionManager.NODE_EXTENSION_TYPE);
+
+ // fill rest
+ trySetProperty(extNode, ExtensionDescriptor.PROP_REP_NAME, name, false);
+ trySetProperty(extNode, ExtensionDescriptor.PROP_REP_ID, id, false);
+ trySetProperty(extNode, ExtensionDescriptor.PROP_REP_CLASS, clazz, false);
+ trySetProperty(extNode, ExtensionDescriptor.PROP_REP_CLASSPATH, classPath, true);
+ trySetProperty(extNode, ExtensionDescriptor.PROP_REP_CONFIGURATION_CLASS, configClass, false);
+
+ // save the node
+ extNode.save();
+ }
+
+ protected static Node ensurePath(Session session, String path) throws RepositoryException {
+ StringTokenizer tokener = new StringTokenizer(path, "/");
+ Node node = session.getRootNode();
+ while (tokener.hasMoreTokens()) {
+ String label = tokener.nextToken();
+
+ if (node.hasNode(label)) {
+ node = node.getNode(label);
+ } else {
+ node = node.addNode(label, "nt:unstructured");
+ }
+ }
+
+ // save all modifications
+ session.save();
+
+ return node;
+ }
+
+ protected static void trySetProperty(Node extNode, String prop, String value,
+ boolean multiple) throws RepositoryException {
+
+ // nothing if no value
+ if (value == null || value.length() == 0) {
+ return;
+ }
+
+ // single value
+ if (!multiple) {
+ extNode.setProperty(prop, value);
+ return;
+ }
+
+ // split multivalue on ","
+ List valueList = new ArrayList();
+ StringTokenizer tokener = new StringTokenizer(value, ",");
+ while (tokener.hasMoreTokens()) {
+ valueList.add(tokener.nextToken());
+ }
+
+ // create value objects
+ ValueFactory vf = extNode.getSession().getValueFactory();
+ Value[] values = new Value[valueList.size()];
+ for (int i=0; i < values.length; i++) {
+ values[i] = vf.createValue((String) valueList.get(i));
+ }
+
+ // set the property
+ extNode.setProperty(prop, values);
+ }
+
+ private void putClass(Session session, String extLoc, String cls) throws RepositoryException {
+ String name = getClass().getName();
+ int lastDot = name.lastIndexOf('.');
+ if (lastDot > 0) name = name.substring(0, lastDot);
+ extLoc += "/classes/" + name.replace('.', '/');
+// extLoc += "/classes/" +
+// base.getPackage().getName().replace('.', '/');
+
+ Node pNode = ensurePath(session, extLoc);
+ Node file = pNode.addNode(cls, "nt:file");
+ Node content = file.addNode("jcr:content", "nt:resource");
+ content.setProperty("jcr:mimeType", "application/octet-stream");
+ content.setProperty("jcr:lastModified", Calendar.getInstance());
+
+ InputStream ins = getClass().getResourceAsStream("/"+cls+".bin");
+ if (ins != null) {
+ try {
+ content.setProperty("jcr:data", ins);
+ } finally {
+ try {
+ ins.close();
+ } catch (IOException ignore) {}
+ }
+ }
+
+ pNode.save();
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFrameworkTestBase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFrameworkTestBase.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionNodeTypeTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionNodeTypeTest.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionNodeTypeTest.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionNodeTypeTest.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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.jackrabbit.extension;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeTypeManager;
+
+/**
+ * The <code>ExtensionNodeTypeTest</code> TODO
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date$
+ */
+public class ExtensionNodeTypeTest extends ExtensionFrameworkTestBase {
+
+ public void testNodeType() throws ExtensionException, RepositoryException {
+ NodeTypeManager ntm= session.getWorkspace().getNodeTypeManager();
+
+ // check whether the node type is available
+ ExtensionManager.checkNodeType(session);
+
+ ntm.getNodeType(ExtensionManager.NODE_EXTENSION_TYPE);
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionNodeTypeTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionNodeTypeTest.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/TestAll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/TestAll.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/TestAll.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/TestAll.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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.jackrabbit.extension;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.jackrabbit.extension.configuration.ItemConfigurationTest;
+
+public class TestAll {
+
+ /**
+ * Returns a <code>Test</code> suite that executes all tests inside this
+ * package.
+ *
+ * @return a <code>Test</code> suite that executes all tests inside this
+ * package.
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Extension Tests");
+
+ suite.addTest(new ExtensionFrameworkTestBase("repositoryStart"));
+ suite.addTestSuite(ExtensionNodeTypeTest.class);
+ suite.addTestSuite(ExtensionFindTest.class);
+ suite.addTestSuite(ItemConfigurationTest.class);
+ suite.addTest(new ExtensionFrameworkTestBase("repositoryStop"));
+
+ return suite;
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/TestAll.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/TestAll.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/configuration/ItemConfigurationTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/configuration/ItemConfigurationTest.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/configuration/ItemConfigurationTest.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/configuration/ItemConfigurationTest.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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.jackrabbit.extension.configuration;
+
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationComparator;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.configuration.StrictConfigurationComparator;
+import org.apache.jackrabbit.extension.ExtensionFrameworkTestBase;
+
+
+public class ItemConfigurationTest extends ExtensionFrameworkTestBase {
+
+ private static final String ROOT_PATH = "/config/test";
+ private static final String CFG1 = ROOT_PATH + "/config1";
+ private static final String CFG2 = ROOT_PATH + "/config2";
+// private static final String CFG3 = ROOT_PATH + "/config3";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ ensurePath(session, ROOT_PATH);
+ }
+
+ protected void tearDown() throws Exception {
+ try {
+ Item item = session.getItem(ROOT_PATH);
+ javax.jcr.Node parent = item.getParent();
+ item.remove();
+ parent.save();
+ } catch (RepositoryException re) {
+ // don't care
+ }
+
+ super.tearDown();
+ }
+
+ public void testCreateAndLoad() throws RepositoryException, ConfigurationException {
+ // this is the manually created
+ Configuration created = createSampleConfig();
+// dumpConfiguration(created);
+
+ // get the loaded
+ javax.jcr.Node cfgNode = createSampleConfig(CFG1);
+ Configuration loaded = new ItemConfiguration(cfgNode);
+// dumpConfiguration(loaded);
+
+ // compare configurations
+ ConfigurationComparator comparator = new StrictConfigurationComparator();
+ assertTrue("Configurations differ", comparator.compare(created, loaded));
+ }
+
+ public void testLoadSave() throws RepositoryException, ConfigurationException {
+ // load configuration
+ javax.jcr.Node cfgNode = createSampleConfig(CFG1);
+ ItemConfiguration loaded = new ItemConfiguration(cfgNode);
+// dumpConfiguration(loaded);
+
+ // store somewhere else
+ Node dest = ensurePath(session, CFG2);
+ loaded.save(dest);
+
+ ItemConfiguration second = new ItemConfiguration(dest);
+// dumpConfiguration(second);
+
+ // compare configurations
+ ConfigurationComparator comparator = new StrictConfigurationComparator();
+ assertTrue("Configurations differ", comparator.compare(loaded, second));
+ }
+
+ public void testLoadAdditions() throws RepositoryException, ConfigurationException {
+ // load configuration
+ javax.jcr.Node cfgNode = createSampleConfig(CFG1);
+ ItemConfiguration loaded = new ItemConfiguration(cfgNode);
+
+ // add to the configuration
+ loaded.addProperty("added.value[@data]", "Added data");
+ loaded.addProperty("typed.added", "Added to typed");
+ loaded.addProperty("typed[@string]", "Another string");
+
+// dumpConfiguration("Loaded", loaded);
+
+ // save to the configuration
+ loaded.save();
+
+ // load the same configuration into a new object
+ ItemConfiguration second = new ItemConfiguration(cfgNode);
+// dumpConfiguration("Second", second);
+
+ // compare configurations
+ ConfigurationComparator comparator = new StrictConfigurationComparator();
+ assertTrue("Configurations differ", comparator.compare(loaded, second));
+ }
+
+ public void testLoadDeletions() throws RepositoryException, ConfigurationException {
+ // load configuration
+ javax.jcr.Node cfgNode = createSampleConfig(CFG1);
+ ItemConfiguration loaded = new ItemConfiguration(cfgNode);
+
+// dumpConfiguration("Loaded - unmodified", loaded);
+
+ // add to the configuration
+ loaded.clearProperty("typed[@string]");
+ loaded.clearProperty("multivalue[@multi](0)");
+ loaded.clearProperty("sns.same(1)");
+
+// dumpConfiguration("Loaded - modified", loaded);
+
+ // save to the configuration
+ loaded.save();
+
+ // load the same configuration into a new object
+ ItemConfiguration second = new ItemConfiguration(cfgNode);
+// dumpConfiguration("Second", second);
+
+ // compare configurations
+ ConfigurationComparator comparator = new StrictConfigurationComparator();
+ assertTrue("Configurations differ", comparator.compare(loaded, second));
+ }
+
+ public void testLoadDeletionsNotSaved() throws RepositoryException, ConfigurationException {
+ // load configuration
+ javax.jcr.Node cfgNode = createSampleConfig(CFG1);
+ ItemConfiguration loaded = new ItemConfiguration(cfgNode);
+
+// dumpConfiguration("Loaded - unmodified", loaded);
+
+ ItemConfiguration unmodified = new ItemConfiguration(cfgNode);
+// dumpConfiguration("Unmodified", unmodified);
+
+ // add to the configuration
+ loaded.clearProperty("typed[@string]");
+ loaded.clearProperty("multivalue[@multi](0)");
+ loaded.clearProperty("sns.same(1)");
+
+// dumpConfiguration("Loaded - modified", loaded);
+
+ // load the same configuration into a new object
+ ItemConfiguration second = new ItemConfiguration(cfgNode);
+// dumpConfiguration("Second", second);
+
+ // compare configurations
+ ConfigurationComparator comparator = new StrictConfigurationComparator();
+
+ // loaded (modified) and second must be different
+ assertFalse("Configurations are the same", comparator.compare(loaded, second));
+
+ // unmodified and second must bethe same
+ assertTrue("Configurations differ", comparator.compare(unmodified, second));
+ }
+
+ protected HierarchicalConfiguration createSampleConfig() {
+ HierarchicalConfiguration config = new HierarchicalConfiguration();
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(0);
+
+ config.addProperty("typed[@string]", "value1");
+ config.addProperty("typed[@boolean]", Boolean.TRUE);
+ config.addProperty("typed[@double]", new Double(2.5D));
+ config.addProperty("typed[@long]", new Long(10L));
+ config.addProperty("typed[@date]", cal);
+
+ for (int i=0; i < 5; i++) {
+ config.addProperty("multivalue[@multi]", "multi[" + i+ "]");
+ }
+
+ for (int i=0; i < 3; i++) {
+ config.addProperty("sns.same", "sample" + i);
+ }
+
+ config.addProperty("nodeValue", "This is the node's value");
+
+ return config;
+ }
+
+ protected javax.jcr.Node createSampleConfig(String cfgRoot) throws RepositoryException {
+ javax.jcr.Node cfg = ensurePath(session, cfgRoot + "/rep:configuration");
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(0);
+
+ // child node with typed properties
+ javax.jcr.Node child = cfg.addNode("typed");
+ child.setProperty("string", "value1");
+ child.setProperty("boolean", true);
+ child.setProperty("double", 2.5D);
+ child.setProperty("long", 10L);
+ child.setProperty("date", cal);
+
+ // child node with multivalue property
+ ValueFactory vf = session.getValueFactory();
+ Value[] multi = new Value[5];
+ for (int i=0; i < multi.length; i++) {
+ multi[i] = vf.createValue("multi[" + i + "]");
+ }
+ child = cfg.addNode("multivalue");
+ child.setProperty("multi", multi);
+
+ // same name sibbling children
+ child = cfg.addNode("sns");
+ child.addNode("same").setProperty("__DEFAULT__", "sample0");
+ child.addNode("same").setProperty("__DEFAULT__", "sample1");
+ child.addNode("same").setProperty("__DEFAULT__", "sample2");
+
+ // __DEFAULT__ value nodes
+ child = cfg.addNode("nodeValue");
+ child.setProperty("__DEFAULT__", "This is the node's value");
+
+ // save everything !!
+ cfg.save();
+
+ return cfg; // .getParent();
+ }
+
+// private void dumpConfiguration(String title, Configuration config) {
+// System.out.println();
+// System.out.println(title);
+// for (int i=0; i < title.length(); i++) {
+// System.out.print('-');
+// }
+// System.out.println();
+//
+// Set keys = new TreeSet();
+// for (Iterator ki=config.getKeys(); ki.hasNext(); ) {
+// keys.add(ki.next());
+// }
+//
+// for (Iterator ki=keys.iterator(); ki.hasNext(); ) {
+// String key = (String) ki.next();
+// System.out.println(key + " ==> " + config.getProperty(key));
+// }
+// }
+}
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/configuration/ItemConfigurationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/configuration/ItemConfigurationTest.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/DevCoreTest.class.bin
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/DevCoreTest.class.bin?rev=358365&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/DevCoreTest.class.bin
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/log4j.properties?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/log4j.properties (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/log4j.properties Wed Dec 21 12:17:51 2005
@@ -0,0 +1,22 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, file
+#log4j.rootLogger=DEBUG, stdout, file
+#log4j.rootLogger=ERROR, stdout, file
+
+log4j.logger.org.apache.jackrabbit.extension.test=DEBUG
+
+# 'stdout' is set to be a ConsoleAppender.
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+
+# 'stdout' uses PatternLayout
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L)\n
+
+# 'file' is set to be a FileAppender.
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.File=jcr.log
+# log4j.appender.file.Append=false
+
+# 'file' uses PatternLayout.
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L)\n
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/log4j.properties
------------------------------------------------------------------------------
svn:eol-style = native