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 [1/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...
Author: fmeschbe
Date: Wed Dec 21 12:17:51 2005
New Revision: 358365
URL: http://svn.apache.org/viewcvs?rev=358365&view=rev
Log:
Adding contributed simple extension framework
Added:
incubator/jackrabbit/trunk/contrib/extension-framework/ (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/HEADER.txt (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/LICENSE.txt (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/project.properties (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/project.xml
incubator/jackrabbit/trunk/contrib/extension-framework/src/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionDescriptor.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionException.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionIterator.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionManager.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionType.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/NodeTypeSupport.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/ConfigurationIODelegate.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/ItemConfiguration.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/PropertiesNodeConfiguration.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/RepositoryConfiguration.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/XMLNodeConfiguration.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/configuration/package.html (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/package.html (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd
incubator/jackrabbit/trunk/contrib/extension-framework/src/main/resources/org/apache/jackrabbit/extension/type.cnd.bak
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/classes.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/configuration.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/deployment.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/instantiating.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/examples/listing.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/index.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/misc.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/navigation.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/site/xdoc/nodetype.xml (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFindTest.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionFrameworkTestBase.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/ExtensionNodeTypeTest.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/TestAll.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/configuration/
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/java/org/apache/jackrabbit/extension/configuration/ItemConfigurationTest.java (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/DevCoreTest.class.bin (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/log4j.properties (with props)
incubator/jackrabbit/trunk/contrib/extension-framework/src/test/resources/repository.xml (with props)
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Dec 21 12:17:51 2005
@@ -0,0 +1,4 @@
+.classpath
+.project
+target
+velocity.log
Added: incubator/jackrabbit/trunk/contrib/extension-framework/HEADER.txt
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/HEADER.txt?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/HEADER.txt (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/HEADER.txt Wed Dec 21 12:17:51 2005
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/HEADER.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/LICENSE.txt
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/LICENSE.txt?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/LICENSE.txt (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/LICENSE.txt Wed Dec 21 12:17:51 2005
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/LICENSE.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/project.properties
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/project.properties?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/project.properties (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/project.properties Wed Dec 21 12:17:51 2005
@@ -0,0 +1,108 @@
+# Copyright 2003-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.
+
+######################################################################
+# Apache Central Repository
+######################################################################
+maven.repo.central=www.apache.org
+maven.repo.central.directory=/www/www.apache.org/dist/java-repository
+maven.remote.group=apcvs
+maven.changelog.factory = org.apache.maven.svnlib.SvnChangeLogFactory
+
+######################################################################
+# JUnit Testing
+######################################################################
+maven.test.failure = false
+maven.junit.fork=true
+maven.junit.dir=${maven.build.dir}
+#maven.junit.sysproperties=org.xml.sax.driver java.security.auth.login.config
+maven.junit.sysproperties=org.xml.sax.driver
+org.xml.sax.driver=org.apache.xerces.parsers.SAXParser
+#java.security.auth.login.config=applications/test/jaas.config
+
+
+#If you wish to skip tests when doing builds, uncomment
+#maven.test.skip = true
+
+######################################################################
+# Checkstyle
+######################################################################
+maven.checkstyle.properties= checkstyle.xml
+maven.linkcheck.enable=false
+
+######################################################################
+# JavaDoc
+#
+# javadoc urls can be added here, multiple urls are appended using a comma
+#
+# maven.javadoc.links = http://foo/bar/api,\
+# http://flim/flam/api/
+######################################################################
+maven.javadoc.links=http://java.sun.com/j2se/1.4.2/docs/api/,http://www.day.com/maven/jsr170/javadocs/jcr-0.16.4.1/
+maven.javadoc.author=false
+maven.javadoc.version=false
+
+######################################################################
+# Other opts
+######################################################################
+# uncomment the next line to work in offline mode (no jar download & no linkcheck)
+#maven.mode.online=
+
+maven.compile.debug=on
+maven.compile.deprecation=off
+maven.compile.optimize=off
+maven.compile.source=1.4
+maven.compile.target=1.4
+
+maven.jarResources.basedir=src/java
+maven.jar.excludes=**/package.html
+
+# Location of the generated query language parsers. Needed for
+# the Maven Eclipse plugin to automatically locate the generated
+# source files. Note that this value matches the hardcoded path
+# in the Maven JavaCC plugin. Therefore, do not change this value!
+maven.gen.src=${maven.build.dir}/generated-src/main
+
+# specifying additional remote repository for downloading dependencies
+# not available at www.ibiblio.org/maven/
+maven.repo.remote = http://www.ibiblio.org/maven/,http://www.day.com/maven/
+
+######################################################################
+# Site L&F
+######################################################################
+# maven.xdoc.jsl=
+maven.xdoc.date=
+maven.xdoc.poweredby.image=maven-feather.png
+maven.xdoc.version=${pom.currentVersion}
+maven.xdoc.developmentProcessUrl=http://incubator.apache.org/projects/jackrabbit.html
+maven.docs.src=${basedir}/src/site/xdoc
+maven.changelog.range=60
+maven.changelog.factory=org.apache.maven.svnlib.SvnChangeLogFactory
+maven.multiproject.overviewPage.title=Jackrabbit components
+
+# ------------------------------------------------------------------------
+# M A V E N J A R O V E R R I D E
+# ------------------------------------------------------------------------
+#maven.jar.override = on
+#maven.jar.jcr = ${basedir}/lib/jcr.jar
+
+######################################################################
+# Site Deploy (into ../jackrabbit-site for checkout on incubator.apache.org)
+######################################################################
+maven.site.deploy.method=fs
+
+# IDE settings
+maven.eclipse.resources.addtoclasspath=true
+
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/project.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/extension-framework/project.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/project.xml?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/project.xml (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/project.xml Wed Dec 21 12:17:51 2005
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<project>
+ <pomVersion>1</pomVersion>
+ <groupId>org.apache.jackrabbit</groupId>
+ <currentVersion>1.0-SNAPSHOT</currentVersion>
+ <organization>
+ <name>The Apache Software Foundation</name>
+ <url>http://incubator.apache.org/projects/jackrabbit.html</url>
+ <logo>http://incubator.apache.org/images/apache-incubator-logo.png</logo>
+ </organization>
+ <inceptionYear>2005</inceptionYear>
+ <package>org.apache.jackrabbit.extension</package>
+ <description>The Jackrabbit Extension Framework is a simple framework providing functionality to easily extend applications
+in a plug-in style.</description>
+ <shortDescription>Extension Framework for JCR Repositories</shortDescription>
+ <repository />
+ <developers>
+ <developer>
+ <name>Felix Meschberger</name>
+ <id>1</id>
+ <email>fmeschbe at apache dot org</email>
+ <organization>Day Software</organization>
+ <timezone>+1</timezone>
+ </developer>
+ </developers>
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>/LICENSE.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+ <reports>
+ <report>maven-javadoc-plugin</report>
+ <report>maven-jdepend-plugin</report>
+ <report>maven-license-plugin</report>
+ </reports>
+ <artifactId>extension-framework</artifactId>
+ <name>Jackrabbit Extension Framework</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>classloader</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>nt-ns-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>jsr170</groupId>
+ <artifactId>jcr</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>commons-configuration</groupId>
+ <artifactId>commons-configuration</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.1</version>
+ <type>jar</type>
+ </dependency>
+ <!-- Unit Testing -->
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.8</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>3.1</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>concurrent</groupId>
+ <artifactId>concurrent</artifactId>
+ <version>1.3.4</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>lucene</groupId>
+ <artifactId>lucene</artifactId>
+ <version>1.4.3</version>
+ <type>jar</type>
+ </dependency>
+ </dependencies>
+ <build>
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>false</filtering>
+ </resource>
+ </resources>
+ <unitTestSourceDirectory>src/test/java</unitTestSourceDirectory>
+ <unitTest>
+ <includes>
+ <include>**/*TestAll.java</include>
+ </includes>
+ <resources>
+ <resource>
+ <directory>src/test/resources</directory>
+ <filtering>false</filtering>
+ </resource>
+ </resources>
+ </unitTest>
+ </build>
+</project>
+
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionDescriptor.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionDescriptor.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionDescriptor.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionDescriptor.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,718 @@
+/*
+ * 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.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.extension.configuration.ItemConfiguration;
+import org.apache.jackrabbit.extension.configuration.RepositoryConfiguration;
+
+/**
+ * The <code>ExtensionDescriptor</code> class implements a descriptor for an
+ * extension defined in a repository node with mixin node type
+ * <code>rep:extension</code>.
+ * <p>
+ * Two instances of this class are considered equal if they are the same
+ * instance or if they are of the same extension type and if their extension
+ * names are equal.
+ * <p>
+ * This class implements the <code>Comparable</code> interface defining an order
+ * amongst two instances of this class according to the extension type
+ * identification and the extension name. See {@link #compareTo(Object)}.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date$
+ *
+ * @see org.apache.jackrabbit.extension.ExtensionType
+ * @see org.apache.jackrabbit.extension.ExtensionManager
+ */
+public class ExtensionDescriptor implements Comparable {
+
+ /** default log */
+ private static final Log log = LogFactory.getLog(ExtensionDescriptor.class);
+
+ /**
+ * The name of the property containing the extension type identification
+ * (value is "rep:id").
+ * This is a mandatory property of an extension node.
+ */
+ public static final String PROP_REP_ID = "rep:id";
+
+ /**
+ * The name of the property containing the extension name (value is
+ * "rep:name").
+ * This is a mandatory property of an extension node.
+ */
+ public static final String PROP_REP_NAME = "rep:name";
+
+ /**
+ * The name of the property containing the fully qualified name of a class
+ * implementing the extension (value is "rep:class").
+ * This is an optional property of the extension node.
+ */
+ public static final String PROP_REP_CLASS = "rep:class";
+
+ /**
+ * The name of the multivalue property containing the class path providing
+ * the extension class(es) (value is "rep:classpath").
+ * This is an optional property of the extension node.
+ */
+ public static final String PROP_REP_CLASSPATH = "rep:classpath";
+
+ /**
+ * The name of the property containing the fully qualified name of a class
+ * implementing the <code>org.apache.commons.configuration.Configuration</code>
+ * interface (value is "rep:configurationClass").
+ * This is an optional property of the extension node.
+ */
+ public static final String PROP_REP_CONFIGURATION_CLASS =
+ "rep:configurationClass";
+
+ /**
+ * The name of the child node containing the configuration for this
+ * extension (value is "rep:configuration").
+ * This is an optional child node of the extension node.
+ */
+ public static final String NODE_REP_CONFIGURATION = "rep:configuration";
+
+ /**
+ * The {@link ExtensionType} to which this extension belongs.
+ * @see #getExtensionType
+ */
+ private final ExtensionType type;
+
+ /**
+ * The <code>Node</code> from which this descriptor has been loaded.
+ * @see #getNode()
+ */
+ private final Node node;
+
+ /**
+ * The extension type identification read from the {@link #PROP_REP_ID}
+ * property of the node describing the extension.
+ * @see #getId()
+ */
+ private final String id;
+
+ /**
+ * The extension name read from the {@link #PROP_REP_NAME} property of the
+ * node describing the extension.
+ * @see #getName()()
+ */
+ private final String name;
+
+ /**
+ * The fully qualified name of the class implementing the extension or
+ * <code>null</code> if none is defined. The value of this field is read
+ * from the {@link #PROP_REP_CLASS} property of the node describing the
+ * extension.
+ * @see #getClassName()
+ */
+ private final String className;
+
+ /**
+ * The classpath to configure on the extension type's class loader to load
+ * and use this extension or <code>null</code> if none is defined. The value
+ * of this field is read from the {@link #PROP_REP_CLASSPATH} property of
+ * the node describing the extension.
+ * @see #getClassPath()
+ */
+ private final String[] classPath;
+
+ /**
+ * The fully qualified name of the class implementing the Apache Jakarta
+ * Commons <code>Configuration</code> interface or <code>null</code> if
+ * none is defined. The value of this field is read from the
+ * {@link #PROP_REP_CONFIGURATION_CLASS} property of the node describing the
+ * extension.
+ * @see #getConfigurationClassName()
+ * @see #getConfiguration()
+ * @see #getConfigurationNode()
+ */
+ private final String configurationClassName;
+
+ /**
+ * The absolute path of the {@link #node} from which this descriptor has
+ * been loaded.
+ * @see #getNodePath();
+ */
+ private String nodePath;
+
+ /**
+ * The extension instance created for this descriptor by the
+ * {@link #getExtension()} method or <code>null</code> if none has been
+ * created yet.
+ * @see #getExtension()
+ */
+ private Object extension;
+
+ /**
+ * The configuration object created for this descriptor by the
+ * {@link #getConfiguration()} method or <code>null</code> if none has been
+ * created yet.
+ * @see #getConfiguration()
+ */
+ private Configuration configuration;
+
+ /**
+ * Creates an instance of this class loading the definition from the given
+ * <code>extensionNode</code>.
+ * <p>
+ * This method does not check whether the node is of the correct type but
+ * merely accesses the properties required to exist and tries to access
+ * optional properties. If an error occurrs accessing the properties,
+ * an <code>ExtensionException</code> is thrown with the cause set.
+ *
+ * @param type The {@link ExtensionType} having loaded this extension
+ * object.
+ * @param extensionNode The <code>Node</code> containing the extension
+ * description.
+ *
+ * @throws ExtensionException If an error occurrs reading the extension
+ * description from the node.
+ */
+ /* package */ ExtensionDescriptor(ExtensionType type, Node extensionNode)
+ throws ExtensionException {
+
+ this.type = type;
+ node = extensionNode;
+
+ try {
+ // required data
+ id = getPropertyOrNull(extensionNode, PROP_REP_ID);
+ name = getPropertyOrNull(extensionNode, PROP_REP_NAME);
+ if (id == null || name == null) {
+ throw new ExtensionException("Missing id or name property");
+ }
+
+ // optional class, classpath and configuration class
+ className = getPropertyOrNull(extensionNode, PROP_REP_CLASS);
+ classPath = getPropertiesOrNull(extensionNode, PROP_REP_CLASSPATH);
+ configurationClassName =
+ getPropertyOrNull(extensionNode, PROP_REP_CONFIGURATION_CLASS);
+ } catch (RepositoryException re) {
+ throw new ExtensionException("Cannot load extension", re);
+ }
+ }
+
+ /**
+ * Returns the {@link ExtensionType} which has loaded this extension.
+ */
+ private ExtensionType getExtensionType() {
+ return type;
+ }
+
+ /**
+ * Returns the <code>Node</code> from which this extension has been loaded.
+ * Any modification to the node returned will only be active the next
+ * time an instance of this class is created from the node.
+ */
+ public final Node getNode() {
+ return node;
+ }
+
+ /**
+ * Returns the absolute path of the <code>Node</code> from which this
+ * extension has been loaded.
+ */
+ public final String getNodePath() {
+ if (nodePath == null) {
+ try {
+ nodePath = getNode().getPath();
+ } catch (RepositoryException re) {
+ log.warn("Cannot get the path of the extension node", re);
+ nodePath = getNode().toString();
+ }
+ }
+
+ return nodePath;
+ }
+
+ /**
+ * Returns the identification of the extension type implemented by this
+ * extension.
+ */
+ public final String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the name of this extension.
+ */
+ public final String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the fully qualified name of the class implementing this extension
+ * or <code>null</code> if none is configured in the extension descriptor
+ * node.
+ */
+ public final String getClassName() {
+ return className;
+ }
+
+ /**
+ * Returns the extension class path or <code>null</code> if none has been
+ * configured in the extension descriptor. Note that an empty array is
+ * never returned by this method.
+ */
+ public final String[] getClassPath() {
+ return classPath;
+ }
+
+ /**
+ * Returns the fully qualified name of the extensions configuration class
+ * or <code>null</code> if none is configured in the extension's node.
+ * @see #getConfiguration()
+ * @see #getConfigurationNode()
+ */
+ public final String getConfigurationClassName() {
+ return configurationClassName;
+ }
+
+ //---------- Instantiation support ----------------------------------------
+
+ /**
+ * Returns the class loader to be used to load the extension object and the
+ * configuration for the extension described by this descriptor.
+ */
+ public ClassLoader getExtensionLoader() {
+ return getExtensionType().getClassLoader(this);
+ }
+
+ /**
+ * Creates an instance of the extension class defined by this descriptor.
+ * <p>
+ * If the descriptor contains a classpath specification, the class loader of
+ * the extension type to which the extension belongs, is configured with the
+ * additional classpath.
+ * <p>
+ * The extension class must provide either of two constructors for it to be
+ * instantiated by this method:
+ * <ol>
+ * <li>If a public constructor taking an instance of
+ * {@link ExtensionDescriptor} is available, that constructor is used to
+ * create the extension instance.</il>
+ * <li>Otherwise if a public default constructor taking no paramaters at
+ * all is available, that constructor is used to create the extension
+ * instance. In this case it is the responsibility of the application to
+ * provide the extension instance with more information if required.</li>
+ * </ol>
+ * <p>
+ * If neither constructor is available in the class, this method fails with
+ * an {@link ExtensionException}.
+ * <p>
+ * If the class provides a public method taking a single parameter of
+ * type <code>ExtensionDescriptor</code>, that method is called with this
+ * instance as the parameter value. This allows for parameterless default
+ * constructors in the extension classes while still getting the extension
+ * descriptor.
+ * <p>
+ * If no class has been defined for this extension, an
+ * <code>IllegalArgumentException</code> is thrown.
+ *
+ * @return The instance created for this extension.
+ *
+ * @throws IllegalArgumentException if no extension class specification is
+ * available in this extension descriptor.
+ * @throws ExtensionException if the extension class has no suitable
+ * constructor or if an error occurrs loading or instantiating the
+ * class.
+ */
+ public Object getExtension() throws ExtensionException {
+
+ // immediately return the extension, if it is already defined
+ if (extension != null) {
+ return extension;
+ }
+ // otherwise, we have to instantiate
+
+ // fail if there is no class name in the descriptor
+ if (getClassName() == null) {
+ throw new IllegalArgumentException("Descriptor has no class definition");
+ }
+
+ try {
+ log.debug("Loading class " + getClassName());
+ Class clazz = getExtensionLoader().loadClass(getClassName());
+ Object extension = instantiate(clazz);
+ setDescriptor(extension);
+ return extension;
+
+ } catch (Exception e) {
+ throw new ExtensionException("Cannot instantiate extension " +
+ getClassName(), e);
+ }
+ }
+
+ /**
+ * Returns the node containing the configuration of this extension. If the
+ * extension's node has a child node <code>rep:configuration</code>, that
+ * child node is returned, otherwise the extension's node is returned.
+ *
+ * @return The configuration node of this extension.
+ */
+ public Node getConfigurationNode() {
+ Node node = getNode();
+
+ try {
+ if (node.hasNode(NODE_REP_CONFIGURATION)) {
+ return node.getNode(NODE_REP_CONFIGURATION);
+ }
+ } catch (RepositoryException re) {
+ log.warn("Cannot check or access configuration node " +
+ NODE_REP_CONFIGURATION + ". Using extension node", re);
+ }
+
+ return node;
+ }
+
+ /**
+ * Returns the <code>Configuration</code> object used to configure this
+ * extension.
+ * <p>
+ * If the extension descriptor does not contain the fully qualified name of
+ * a configuration class, this method returns an instance of the
+ * {@link ItemConfiguration} class loaded from the extension's node.
+ * <p>
+ * Otherwise the named class is loaded through the extensions class loader
+ * (see {@link #getExtensionLoader()}) and instantiated. A class to be used
+ * like this must implement the <code>Configuration</code> interface and
+ * provide a public default constructor. If any of the requirements is not
+ * met by the configured class, this method throws an exception.
+ * <p>
+ * If the configured class implements the {@link RepositoryConfiguration}
+ * interface, the configuration is configured with the extension's node
+ * and loaded.
+ * <p>
+ * The main use of this method is for the extension class itself to
+ * configure itself. Another use may be for an administrative application
+ * to update configuration and optionally store it back.
+ *
+ * @return The <code>Configuration</code> object used to configured this
+ * extension.
+ *
+ * @throws ExtensionException If the configuration class has no public
+ * default constructor or if the configuration class is not an
+ * implementation of the <code>Configuration</code> interface or if an
+ * error occurrs loading or instantiating the configuration class.
+ */
+ public Configuration getConfiguration() throws ExtensionException {
+ // immediately return the configuration, if it is already defined
+ if (configuration != null) {
+ return configuration;
+ }
+ // otherwise, we have to instantiate
+
+ // use a default configuration if no specific class defined
+ if (getConfigurationClassName() == null) {
+ log.debug("No configurationClass setting, using ItemConfiguration");
+ try {
+ return new ItemConfiguration(getConfigurationNode());
+ } catch (ConfigurationException ce) {
+ throw new ExtensionException(
+ "Cannot load ItemConfiguration from " + getNodePath());
+ }
+ }
+
+ try {
+ log.debug("Loading class " + getConfigurationClassName());
+ Class clazz =
+ getExtensionLoader().loadClass(getConfigurationClassName());
+
+ // create an instance using the one taking an extension descriptor
+ // if available otherwise use the default constructor
+ log.debug("Creating configuration object instance");
+ Object configObject = clazz.newInstance();
+ if (!(configObject instanceof Configuration)) {
+ throw new ExtensionException("Configuration class " +
+ getClassName() +
+ " does not implement Configuration interface");
+ }
+
+ // load the repository configuration from the extension node
+ if (configObject instanceof RepositoryConfiguration) {
+ RepositoryConfiguration repoConfig =
+ (RepositoryConfiguration) configObject;
+ repoConfig.setNode(getConfigurationNode());
+ repoConfig.load();
+ }
+
+ configuration = (Configuration) configObject;
+ return configuration;
+
+ } catch (Exception e) {
+ throw new ExtensionException("Cannot instantiate extension " +
+ getClassName(), e);
+ }
+ }
+
+ //---------- Comparable interface -----------------------------------------
+
+ /**
+ * Compares this object with the specified object for order. Returns a
+ * negative integer, zero, or a positive integer as this object is less
+ * than, equal to, or greater than the specified object.
+
+ * @param obj the Object to be compared, which must be an instance of this
+ * class.
+ *
+ * @return a negative integer, zero, or a positive integer as this
+ * descriptor is less than, equal to, or greater than the specified
+ * descriptor.
+ *
+ * @throws NullPointerException if <code>obj</code> is <code>null</code>.
+ * @throws ClassCastException if <code>obj</code> is not an
+ * <code>ExtensionDescriptor</code>.
+ */
+ public int compareTo(Object obj) {
+ // throws documented ClassCastException
+ ExtensionDescriptor other = (ExtensionDescriptor) obj;
+
+ // check the order amongst the id and return if not equal
+ int idOrder = id.compareTo(other.id);
+ if (idOrder != 0) {
+ return idOrder;
+ }
+
+ // id's are the same, so return order amongst names
+ return name.compareTo(other.name);
+ }
+
+ //---------- Object overwrite ---------------------------------------------
+
+ /**
+ * Returns a combined hash code of the {@link #getId() type identification}
+ * and the {@link #getName() name} of this extension as this extension's
+ * hash code.
+ */
+ public int hashCode() {
+ return id.hashCode() + 17 * name.hashCode();
+ }
+
+ /**
+ * Returns <code>true</code> if <code>obj</code> is the same as this or
+ * if it is a <code>ExtensionDescriptor</code> whose type identification
+ * and name equals the type identification and name of this extension.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ } else if (obj instanceof ExtensionDescriptor) {
+ ExtensionDescriptor other = (ExtensionDescriptor) obj;
+ return id.equals(other.id) && name.equals(other.name);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns a string representation of this extension descriptor which
+ * contains the extension type identification and the extension name.
+ */
+ public String toString() {
+ return "Extension " + id + ":" + name;
+ }
+
+ //---------- innternal ----------------------------------------------------
+
+ /**
+ * Returns the value of the {@link #PROP_REP_NAME} property of the
+ * <code>extensionNode</code> or <code>null</code> if no such property
+ * exists.
+ *
+ * @param extensionNode The <code>Node</code> whose extension name property
+ * value is to bereturned.
+ *
+ * @throws RepositoryException if an error occurrs accessing the extension
+ * name property.
+ */
+ /* package */ static String getExtensionName(Node extensionNode)
+ throws RepositoryException {
+ return getPropertyOrNull(extensionNode, PROP_REP_NAME);
+ }
+
+ /**
+ * Returns the string value of the named (single-value) property of the
+ * node or <code>null</code> if the the property does not exists or its
+ * value is empty.
+ *
+ * @param node The <code>Node</code> containing the named property.
+ * @param property The name of the property to reutrn.
+ *
+ * @return The property's string value or <code>null</code> if the property
+ * does not exist or is empty.
+ *
+ * @throws RepositoryException If an error occurrs accesing the node or
+ * property.
+ */
+ private static String getPropertyOrNull(Node node, String property)
+ throws RepositoryException {
+ if (node.hasProperty(property)) {
+ String value = node.getProperty(property).getString();
+ return (value == null || value.length() == 0) ? null : value;
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the string values of the named (multi-valued) property of the
+ * node or <code>null</code> if the the property does not exists or its
+ * value is empty.
+ *
+ * @param node The <code>Node</code> containing the named property.
+ * @param property The name of the property to reutrn.
+ *
+ * @return A string array containing the string representations of the
+ * property's values or <code>null</code> if the property does not
+ * exist or is empty.
+ *
+ * @throws RepositoryException If an error occurrs accesing the node or
+ * property.
+ */
+ private static String[] getPropertiesOrNull(Node node, String property)
+ throws RepositoryException {
+
+ if (node.hasProperty(property)) {
+ Value[] clsPath = node.getProperty(property).getValues();
+ if (clsPath != null && clsPath.length >= 0) {
+ List pathList = new ArrayList();
+ for (int i=0; i < clsPath.length; i++) {
+ String pathEntry = clsPath[i].getString().trim();
+
+ // ignore empty or existing path entry
+ if (pathEntry.length() == 0 ||
+ pathList.contains(pathEntry)) {
+ continue;
+ }
+
+ // new class path entry, add
+ pathList.add(pathEntry);
+ }
+
+ if (pathList.size() > 0) {
+ return (String[]) pathList.toArray(new String[pathList.size()]);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates an instance of the given <code>clazz</code>. If the class has
+ * a public constructor taking a single parameter of type
+ * <code>ExtensionDescriptor</code> that constructor is used to create the
+ * instance. Otherwise the public default constructor is used if available.
+ * If none of both is available or if an error occurrs creating the instance
+ * a <code>ExtensionException</code> is thrown.
+ *
+ * @param clazz The <code>Class</code> to instantiate.
+ *
+ * @return The instance created.
+ *
+ * @throws ExtensionException If an error occurrs instantiating the class.
+ * If instantiation failed due to an exception while calling the
+ * constructor, the causing exception is available as the cause of
+ * the exception.
+ */
+ private Object instantiate(Class clazz) throws ExtensionException {
+ // find constructors (taking descriptor and default)
+ Constructor defaultConstr = null;
+ Constructor descrConstr = null;
+ Constructor[] constructors = clazz.getConstructors();
+ for (int i=0; i < constructors.length; i++) {
+ Class parms[] = constructors[i].getParameterTypes();
+ if (parms.length == 0) {
+ defaultConstr = constructors[i];
+ } else if (parms.length == 1 && parms[i].equals(getClass())) {
+ descrConstr = constructors[i];
+ }
+ }
+
+ try {
+ // create an instance using the one taking an extension descriptor
+ // if available otherwise use the default constructor
+ if (descrConstr != null) {
+ log.debug("Creating instance with descriptor " + this);
+ return descrConstr.newInstance(new Object[]{ this });
+ } else if (defaultConstr != null) {
+ log.debug("Creating default instance without descriptor");
+ return defaultConstr.newInstance(null);
+ } else {
+ throw new ExtensionException("No suitable constructor found " +
+ "to instantiate " + getClassName());
+ }
+ } catch (InstantiationException ie) {
+ throw new ExtensionException(
+ "Cannot instantiate " + getClassName(), ie);
+ } catch (IllegalAccessException iae) {
+ throw new ExtensionException("Cannot access constructor of "
+ + getClassName(), iae);
+ } catch (InvocationTargetException ite) {
+ throw new ExtensionException("Error while instantiating "
+ + getClassName(), ite);
+ }
+ }
+
+ /**
+ * Calls a method taking a single parameter of type
+ * <code>ExtensionDescriptor</code> to provide the extension descriptor to
+ * the extension loaded.
+ * <p>
+ * If an error occurrs calling a method found, an WARN message is logged and
+ * other methods according to the required signature are looked for. If no
+ * suitable method can be found, an INFO method is logged and the extension
+ * could not be provided with the extension descriptor.
+ *
+ * @param extension The extension to provide witch the extension descriptor.
+ */
+ private void setDescriptor(Object extension) {
+ Method[] methods = extension.getClass().getMethods();
+ for (int i=0; i < methods.length; i++) {
+ Class[] parTypes = methods[i].getParameterTypes();
+ if (parTypes.length == 1 && parTypes[0].equals(getClass())) {
+ try {
+ methods[i].invoke(extension, new Object[]{ this });
+ return;
+ } catch (Exception ite) {
+ log.warn("setDescriptor: Calling " +
+ extension.getClass().getName() + "." +
+ methods[i].getName() + " failed", ite);
+ }
+ }
+ }
+
+ log.info("setDescriptor: No setter method for ExtensionDescriptor " +
+ "found in class " + extension.getClass().getName() +
+ " of extension " + getId() + ":" + getName());
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionDescriptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionDescriptor.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionException.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionException.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionException.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionException.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+/**
+ * The <code>ExtensionException</code> class defines an exception which may be
+ * thrown in the Jackrabbit Extension Framework.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date$
+ */
+public class ExtensionException extends Exception {
+
+ /**
+ * serialization identification
+ */
+ private static final long serialVersionUID = 535080559025771531L;
+
+ /**
+ * Creates an instance of this exception with a message.
+ *
+ * @param message The message describing the problem.
+ */
+ public ExtensionException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates an instance of this exception with causing <code>Throwable</code>.
+ *
+ * @param cause The <code>Throwable</code> causing the problem.
+ */
+ public ExtensionException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates an instance of this exception with a message and a causing
+ * <code>Throwable</code>.
+ *
+ * @param message The message describing the problem.
+ * @param cause The <code>Throwable</code> causing the problem.
+ */
+ public ExtensionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionException.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionIterator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionIterator.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionIterator.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionIterator.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,137 @@
+/*
+ * 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 java.util.NoSuchElementException;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The <code>ExtensionIterator</code> class implements the iterator
+ * over instances of the {@link ExtensionDescriptor}s.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date$
+ */
+public class ExtensionIterator implements Iterator {
+
+ /** Default log */
+ private static final Log log = LogFactory.getLog(ExtensionIterator.class);
+
+ /**
+ * The type of the extension descriptors returned.
+ */
+ private final ExtensionType type;
+
+ /**
+ * The underlying iterator of nodes containing the extension descriptors.
+ */
+ private final NodeIterator nodes;
+
+ /**
+ * The preloaded next <code>EventDescriptor</code>. If <code>null</code>
+ * no more descriptors are available in this iterator.
+ */
+ private ExtensionDescriptor next;
+
+ /**
+ * Creates an instance for the given underlying iterator of nodes.
+ *
+ * @param nodes The underlying <code>NodeIterator</code>.
+ */
+ /* package */ ExtensionIterator(ExtensionType type, NodeIterator nodes) {
+ this.type = type;
+ this.nodes = nodes;
+ seek();
+ }
+
+ /**
+ * Returns <code>true</code> if there is at least one more extension
+ * descriptor available in this iterator.
+ */
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ /**
+ * Returns the next available extension descriptor.
+ *
+ * @throws NoSuchElementException If no more extension descriptors are
+ * available.
+ */
+ public Object next() {
+ return nextExtension();
+ }
+
+ /**
+ * Returns the next available extension descriptor.
+ *
+ * @throws NoSuchElementException If no more extension descriptors are
+ * available.
+ */
+ public ExtensionDescriptor nextExtension() {
+ if (next == null) {
+ throw new NoSuchElementException("No more Descriptors");
+ }
+
+ ExtensionDescriptor toReturn = next;
+ seek();
+ return toReturn;
+ }
+
+ /**
+ * Throws <code>UnsupportedOpertationException</code> because this
+ * method is not supported by this implementation.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException("remove");
+ }
+
+ /**
+ * Preload the next <code>ExtensionDescriptor</code> from the next node
+ * in the underlying node iterator.
+ * <p>
+ * If an error occurrs instantiating an extension descriptor for any
+ * node in the iterator, the node is ignored and the next node is
+ * used. This is repeated until either no more nodes are available in
+ * the underlying iterator or an extension descriptor can sucessfully
+ * be created.
+ */
+ private void seek() {
+ while (nodes.hasNext()) {
+ try {
+ Node extNode = nodes.nextNode();
+ String name = ExtensionDescriptor.getExtensionName(extNode);
+ next = type.getOrCreateExtension(name, extNode);
+ return;
+ } catch (RepositoryException re) {
+ log.warn("Cannot get the extension name", re);
+ } catch (ExtensionException ee) {
+ log.warn("Cannot create extensions descriptor", ee);
+ }
+ }
+
+ // fallback if no more nodes
+ next = null;
+ }
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionIterator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionIterator.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionManager.java?rev=358365&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionManager.java (added)
+++ incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionManager.java Wed Dec 21 12:17:51 2005
@@ -0,0 +1,315 @@
+/*
+ * 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 java.util.Map;
+import java.util.TreeMap;
+
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Workspace;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.classloader.RepositoryClassLoader;
+
+/**
+ * The <code>ExtensionManager</code> class provides the core functionality
+ * of the Jackrabbit Extension Framework by methods for finding extensions.
+ * <p>
+ * Instances of this class are created with a <code>Session</code> to the
+ * repository. Consequently all access to the repository is confined to the
+ * workspace to which the session is attached. That is, only extensions located
+ * in the session's workspace are found.
+ * <p>
+ * Additionally the class provides functionality to define the extension node
+ * types on demand.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date$
+ */
+public final class ExtensionManager {
+
+ /** default logger */
+ private static final Log log = LogFactory.getLog(ExtensionManager.class);
+
+ /**
+ * The name of the repository node type defining the properties making up
+ * an extension description (value is "rep:extension").
+ */
+ public static final String NODE_EXTENSION_TYPE = "rep:extension";
+
+ /**
+ * The session providing access to the repository for loading extensions.
+ */
+ private final Session session;
+
+ /**
+ * The application's class loader as provided to the constructor.
+ */
+ private final ClassLoader applicationLoader;
+
+ /**
+ * The map of extension types by the extension type identifiers.
+ */
+ private Map extensionTypes;
+
+ /**
+ * Creates an instance of this manager accessing the repository through the
+ * given <code>session</code>.
+ * <p>
+ * This also confines the extensions available to this manager to the
+ * extensions available through the workspace accessed by the
+ * <code>session</code>.
+ * <p>
+ * If the <code>applicationLoader</code> parameter is <code>null</code>
+ * either the current thread's context class loader is used or if that one
+ * is <code>null</code>, too, the class loader of this class is used.
+ * It is recommended, that the caller of the constructor provides a
+ * non-<code>null</code> class loader to prevent unexpected class loading
+ * issues.
+ * <p>
+ * To make sure extensions may actually be correctly handled, the
+ * {@link #checkNodeType(Session)} method is called.
+ *
+ * @param session The <code>Session</code> to search for and load extensions.
+ * @param applicationLoader The <code>ClassLoader</code> used as the parent
+ * for the repository class loaders.
+ *
+ * @throws NullPointerException If <code>session</code> is <code>null</code>.
+ */
+ public ExtensionManager(Session session, ClassLoader applicationLoader)
+ throws ExtensionException {
+
+ // check session
+ if (session == null) {
+ throw new NullPointerException("session");
+ }
+
+ // make sure the extension system node type is available
+ checkNodeType(session);
+
+ // make sure the application class loader is non-null
+ // - first try current thread context loader
+ // - otherwise use this class's class loader
+ if (applicationLoader == null) {
+ applicationLoader = Thread.currentThread().getContextClassLoader();
+ }
+ if (applicationLoader == null) {
+ applicationLoader = getClass().getClassLoader();
+ }
+
+ // assign fields
+ this.session = session;
+ this.applicationLoader = applicationLoader;
+ }
+
+ /**
+ * Searches in the workspace of this instance's <code>Session</code> for
+ * extensions of type <code>id</code> returning an <code>Iterator</code>
+ * of {@link ExtensionDescriptor} instances. If <code>root</code> is
+ * non-<code>null</code> the search for extensions only takes place in the
+ * indicated subtree.
+ * <p>
+ * <b>NOTE</B>: This method may return more than one extension with the same
+ * name for a given <code>id</code>. This is the only place in the Jackrabbit
+ * Extension Framework which handles duplicate extension names. The rest
+ * relies on extensions to have unique <code>id</code>/name pairs.
+ * <p>
+ * Calling this method multiple times with the same <code>id</code> will
+ * return the same {@link ExtensionDescriptor} instances. Previously
+ * available instances will not returned though if their extension node
+ * has been removed in the meantime. Such instances will still be available
+ * through {@link #getExtension(String, String, String)} but will not be
+ * available on next system restart.
+ *
+ * @param id The extension type identification describing the extensions to
+ * be found.
+ * @param root The root node below which the extensions are looked for. This
+ * path is taken as an absolute path regardless of whether it begins
+ * with a slash or not. If <code>null</code> or empty, the search
+ * takes place in the complete workspace.
+ *
+ * @return An <code>Iterator</code> of {@link ExtensionDescriptor} instances
+ * describing the extensions found.
+ *
+ * @throws IllegalArgumentException If <code>id</code> is empty or
+ * <code>null</code>.
+ * @throws ExtensionException If an error occurrs looking for extensions.
+ */
+ public Iterator getExtensions(String id, String root)
+ throws ExtensionException {
+
+ // delegate finding/loading to the extension type
+ return getExtensionType(id).getExtensions(root);
+ }
+
+ /**
+ * Searches in the workspace of this instance's <code>Session</code> for
+ * an extension with the given <code>name</code> of type <code>id</code>.
+ * If <code>root</code> is non-<code>null</code> the search for extensions
+ * only takes place in the indicated subtree.
+ * <p>
+ * This method fails with an exception if more than one extension with the
+ * same name of the same type is found in the workspace. Not finding the
+ * requested extension also yields an exception.
+ * <p>
+ * Two consecutive calls to this method with the same arguments, namely
+ * the same <code>id</code> and <code>name</code> will return the same
+ * {@link ExtensionDescriptor} instance.
+ *
+ * @param id The extension type identification describing the extensions to
+ * be found.
+ * @param name The name of the extension of the indicated type to be found.
+ * @param root The root node below which the extensions are looked for. This
+ * path is taken as an absolute path regardless of whether it begins
+ * with a slash or not. If <code>null</code> or empty, the search
+ * takes place in the complete workspace.
+ *
+ * @return The named {@link ExtensionDescriptor} instances.
+ *
+ * @throws IllegalArgumentException If <code>id</code> or <code>name</code>
+ * is empty or <code>null</code>.
+ * @throws ExtensionException If no or more than one extensions with the
+ * same name and type can be found or if another error occurrs looking
+ * for extensions.
+ */
+ public ExtensionDescriptor getExtension(String id, String name, String root)
+ throws ExtensionException {
+
+ // delegate finding/loading to the extension type
+ return getExtensionType(id).getExtension(name, root);
+ }
+
+ //---------- Extension type helper methods --------------------------------
+
+ /**
+ * Creates a new instance of the <code>RepositoryClassLoader</code> class
+ * with an empty path accessing the repository through the session of this
+ * manager instance.
+ * <p>
+ * Note, that each call to this method returns a new RepositoryClassLoader
+ * instance.
+ */
+ /* package */ RepositoryClassLoader createClassLoader() {
+ return new RepositoryClassLoader(session, new String[0],
+ applicationLoader);
+ }
+
+ /**
+ * Executes the given XPath query on this mnanager's session and returns
+ * a <code>NodeIterator</code> over the nodes matching the query.
+ *
+ * @param xpath The XPath query to execute
+ *
+ * @return The <code>NodeIterator</code> on the nodes matching the query.
+ *
+ * @throws ExtensionException If an error occurrs executing the query.
+ * The underlying exception is available as the cause of the exception.
+ */
+ /* package */ NodeIterator findNodes(String xpath) throws ExtensionException {
+ try {
+ // look for the extension nodes
+ QueryManager qm = session.getWorkspace().getQueryManager();
+ Query query = qm.createQuery(xpath, Query.XPATH);
+ QueryResult res = query.execute();
+
+ // check whether we found at least one node
+ return res.getNodes();
+ } catch (RepositoryException re) {
+ throw new ExtensionException("Problem executing query '" +
+ xpath + "'", re);
+ }
+ }
+
+ //---------- internal helper ----------------------------------------------
+
+ /**
+ * Returns an {@link ExtensionType} instance for the given name.
+ *
+ * @throws IllegalArgumentException if <code>id</code> is <code>null</code>
+ * or an empty string.
+ */
+ /* package */ ExtensionType getExtensionType(String id) {
+ if (id == null || id.length() == 0) {
+ throw new IllegalArgumentException("Extension type identifier " +
+ "must not be null or empty string");
+ }
+
+ if (extensionTypes == null) {
+ extensionTypes = new TreeMap();
+ }
+
+ ExtensionType type = (ExtensionType) extensionTypes.get(id);
+ if (type == null) {
+ type = new ExtensionType(this, id);
+ extensionTypes.put(id, type);
+ }
+
+ return type;
+ }
+
+ /**
+ * Makes sure the <code>rep:extension</code> node type is registered with
+ * the <code>session</code>'s repository.
+ * <p>
+ * If the required extension descriptor node type is not defined in the
+ * repository yet, it is tried to be registered. If an error occurrs
+ * registering the node type a message is logged and an
+ * <code>ExtensionException</code> is thrown.
+ *
+ * @param session The <code>Session</code> used to access the repository
+ * to test and optionally register the node.
+ *
+ * @throws ExtensionException If an error occurrs checking ro defining the
+ * node type.
+ */
+ public static void checkNodeType(Session session) throws ExtensionException {
+ // quick check for the node type, succeed if defined
+ try {
+ session.getWorkspace().getNodeTypeManager().getNodeType(NODE_EXTENSION_TYPE);
+ log.debug("Required node type exists, can expand archives");
+ return;
+ } catch (NoSuchNodeTypeException nst) {
+ log.debug("Required node types does not exist, try to define");
+ } catch (RepositoryException re) {
+ log.debug("Cannot check for required node type, cannot expand " +
+ "archives", re);
+ throw new ExtensionException("Cannot check for required node type", re);
+ }
+
+ try {
+ Workspace workspace = session.getWorkspace();
+ if (!NodeTypeSupport.registerNodeType(workspace)) {
+ throw new ExtensionException("Registering required node type failed");
+ }
+ } catch (ExtensionException ee) {
+ throw ee;
+ } catch (Throwable t) {
+ // Prevent anything from hapening if node type registration fails
+ // due to missing libraries or other errors
+ log.debug("Error registering node type", t);
+ throw new ExtensionException("Cannot register required node type", t);
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/jackrabbit/trunk/contrib/extension-framework/src/main/java/org/apache/jackrabbit/extension/ExtensionManager.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url