jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmesc...@apache.org
Subject svn commit: r358296 [1/5] - in /incubator/jackrabbit/trunk/contrib/classloader: ./ 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/classloader/ src/main...
Date Wed, 21 Dec 2005 14:14:24 GMT
Author: fmeschbe
Date: Wed Dec 21 06:13:56 2005
New Revision: 358296

URL: http://svn.apache.org/viewcvs?rev=358296&view=rev
Log:
Adding contributed repository class loader

Added:
    incubator/jackrabbit/trunk/contrib/classloader/
    incubator/jackrabbit/trunk/contrib/classloader/HEADER.txt   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/LICENSE.txt   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/project.properties   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/project.xml
    incubator/jackrabbit/trunk/contrib/classloader/src/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ArchiveClassPathEntry.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassLoaderResource.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassPathEntry.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DirectoryClassPathEntry.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DynamicPatternPath.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DynamicRepositoryClassLoader.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ExpandingArchiveClassPathEntry.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/NodeTypeSupport.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/PatternPath.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/RepositoryClassLoader.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/Util.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/net/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/net/FileParts.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/net/JCRJarURLConnection.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/net/JCRJarURLHandler.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/net/JCRURLConnection.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/net/JCRURLHandler.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/net/URLFactory.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/main/resources/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/resources/org/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/resources/org/apache/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/resources/org/apache/jackrabbit/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/resources/org/apache/jackrabbit/classloader/
    incubator/jackrabbit/trunk/contrib/classloader/src/main/resources/org/apache/jackrabbit/classloader/type.cnd
    incubator/jackrabbit/trunk/contrib/classloader/src/test/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/apache/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/apache/jackrabbit/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/apache/jackrabbit/classloader/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/apache/jackrabbit/classloader/AbstractClassLoaderTest.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/apache/jackrabbit/classloader/DynamicRepositoryClassLoaderTest.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/apache/jackrabbit/classloader/ExpandingArchiveClassPathEntryTest.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/apache/jackrabbit/classloader/PatternPathTest.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/java/org/apache/jackrabbit/classloader/TestAll.java   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/log4j.properties   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/mock.jar   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/org/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/org/apache/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/org/apache/jackrabbit/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/org/apache/jackrabbit/classloader/
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/org/apache/jackrabbit/classloader/PatternPathTest.preload.properties   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/other.txt   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/preload.properties   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/readme.txt   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/repository.xml   (with props)
    incubator/jackrabbit/trunk/contrib/classloader/src/test/resources/test1.txt   (with props)

Added: incubator/jackrabbit/trunk/contrib/classloader/HEADER.txt
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/classloader/HEADER.txt?rev=358296&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/classloader/HEADER.txt (added)
+++ incubator/jackrabbit/trunk/contrib/classloader/HEADER.txt Wed Dec 21 06:13:56 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/classloader/HEADER.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/classloader/LICENSE.txt
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/classloader/LICENSE.txt?rev=358296&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/classloader/LICENSE.txt (added)
+++ incubator/jackrabbit/trunk/contrib/classloader/LICENSE.txt Wed Dec 21 06:13:56 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/classloader/LICENSE.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/classloader/project.properties
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/classloader/project.properties?rev=358296&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/classloader/project.properties (added)
+++ incubator/jackrabbit/trunk/contrib/classloader/project.properties Wed Dec 21 06:13:56 2005
@@ -0,0 +1,107 @@
+#  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.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/classloader/project.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/classloader/project.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/classloader/project.xml?rev=358296&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/classloader/project.xml (added)
+++ incubator/jackrabbit/trunk/contrib/classloader/project.xml Wed Dec 21 06:13:56 2005
@@ -0,0 +1,129 @@
+<?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.classloader</package>
+    <description>Classloader is an independent subproject of the Jackrabbit project. It provides support for loading classes from from Java Content Repository for Java Technology API (JCR) implementations. Although implemented as a contribution to the Jackrabbit project, the Jackrabbit Repository Classloader layer is independent of the underlying JCR repository implementation, with a small exception regarding node type creation.</description>
+    <shortDescription>Java Classloader for JCR Repositories</shortDescription>
+    <repository />
+    <developers>
+        <developer>
+            <name>Felix Meschberger</name>
+            <id>1</id>
+            <email>fmeschbe@apache.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>classloader</artifactId>
+    <name>Jackrabbit Repository Classloader</name>
+    <dependencies>
+        <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>
+
+        <!-- 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>
+	        </resource>
+	    </resources>
+        <unitTestSourceDirectory>src/test/java</unitTestSourceDirectory>
+        <unitTest>
+            <includes>
+                <include>**/*TestAll.java</include>
+            </includes>
+            <resources>
+                <resource>
+                    <directory>src/test/resources</directory>
+                </resource>
+            </resources>
+        </unitTest>
+    </build>
+</project>
+

Added: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ArchiveClassPathEntry.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ArchiveClassPathEntry.java?rev=358296&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ArchiveClassPathEntry.java (added)
+++ incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ArchiveClassPathEntry.java Wed Dec 21 06:13:56 2005
@@ -0,0 +1,578 @@
+/*
+ * 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.classloader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.net.URLFactory;
+
+
+/**
+ * The <code>ArchiveClassPathEntry</code> implements the {@link ClassPathEntry}
+ * abstract class with support for archives containing classes and other
+ * resources. The path used to construct the instance is the path of an item
+ * resolving to a property containing the jar archive to access.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date:$
+ */
+class ArchiveClassPathEntry extends ClassPathEntry {
+
+    /** Default logger */
+    private static final Log log =
+        LogFactory.getLog(ArchiveClassPathEntry.class);
+
+    /** The property containing the archive */
+    private final Property prop;
+
+    /**
+     * Cache all entries in the archive for faster decision on whether such
+     * an entry is contained.
+     */
+    private Map entryMap;
+
+    /**
+     * The JAR file manifest. Set on demand by the {@link #getManifest()}
+     * method.
+     */
+    private Manifest jarManifest;
+
+    /**
+     * Flag to indicate, whether the {@link #jarManifest} has already been read
+     * from the archive. This field is used and set by the
+     * {@link #getManifest()} to decide, whether to try to read the manifest.
+     */
+    private boolean jarManifestRead;
+
+    /**
+     * Creates an instance of the <code>ArchiveClassPathEntry</code> class.
+     *
+     * @param prop The <code>Property</code> containing the archive and
+     *      the session used to access the repository.
+     * @param path The original class path entry leading to the creation of
+     *      this instance. This is not necessairily the same path as the
+     *      properties path if the property was found through the primary
+     *      item chain.
+     *
+     * @throws RepositoryException If an error occurrs retrieving the session
+     *      from the property.
+     */
+    ArchiveClassPathEntry(Property prop, String path) throws RepositoryException {
+        super(prop.getSession(), path);
+        this.prop = prop;
+    }
+
+    /**
+     * Clones the indicated <code>ArchiveClassPathEntry</code> object by
+     * taking over its path, session and property.
+     *
+     * @param base The base <code>ArchiveClassPath</code> entry to clone.
+     *
+     * @see ClassPathEntry#ClassPathEntry(ClassPathEntry)
+     */
+    protected ArchiveClassPathEntry(ArchiveClassPathEntry base) {
+        super(base);
+        this.prop = base.prop;
+    }
+
+    /**
+     * Returns the <code>Property</code> containing the JAR file of this
+     * archive class path entry.
+     */
+    protected Property getProperty() {
+        return prop;
+    }
+
+    /**
+     * Returns a {@link ClassLoaderResource} for the named resource if it
+     * can be found in the archive identified by the path given at
+     * construction time. Note that if the archive property would exist but is
+     * not readable by the current session, no resource is returned.
+     * <p>
+     * This method accesses the archive through an <code>InputStream</code>
+     * retrievedfrom the property. This <code>InputStream</code> is closed before
+     * returning to the caller to release the resources behind the stream
+     * such that it might be updated, etc. For this reason the resource
+     * instance returned will again open an <code>InputStream</code> on the
+     * archive property to access the resource. Users of the resource
+     * <code>InputStream</code> are encouraged to close the stream when no
+     * longer used to prevent lockups in the Repository.
+     *
+     * @param name The name of the resource to return. If the resource would
+     *      be a class the name must already be modified to denote a valid
+     *      path, that is dots replaced by slashes and the <code>.class</code>
+     *      extension attached.
+     *
+     * @return The {@link ClassLoaderResource} identified by the name or
+     *      <code>null</code> if no resource is found for that name.
+     */
+    public ClassLoaderResource getResource(final String name) {
+
+        JarInputStream zins = null;
+        try {
+            // get the archive and try to find the entry
+            zins = getJarInputStream(prop);
+            JarEntry entry = findEntry(zins, name);
+
+            // if found create the resource to return
+            if (entry != null) {
+                return new ArchiveClassPathResource(this, entry);
+            }
+
+            log.debug("getResource: resource " + name + " not found"
+                + " in archive " + path);
+
+        } catch (IOException ioe) {
+
+            log.warn("getResource: problem accessing the archive " + path
+                + " for " + name + ": " + ioe.toString());
+
+        } catch (RepositoryException re) {
+
+            log.warn("getResource: problem accessing the archive " + path
+                + " for " + name + ": " + re.toString());
+
+        } finally {
+
+            // make sure streams are closed at the end
+            if (zins != null) {
+                try {
+                    zins.close();
+                } catch (IOException ignore) {
+                }
+            }
+
+        }
+        // invariant : not found or problem accessing the archive
+
+        return null;
+    }
+
+    /**
+     * Returns a <code>ClassPathEntry</code> with the same configuration as
+     * this <code>ClassPathEntry</code>.
+     * <p>
+     * The <code>ArchiveClassPathEntry</code> class has internal state.
+     * Therefore a new instance is created from the unmodifiable configuration
+     * of this instance.
+     */
+    ClassPathEntry copy() {
+        return new ArchiveClassPathEntry(this);
+    }
+
+    /**
+     * Returns a JAR URL with no entry as the base URL of this class path entry.
+     */
+    public URL toURL() {
+        if (baseURL == null) {
+            try {
+                baseURL = URLFactory.createJarURL(session, path, null);
+            } catch (MalformedURLException mue) {
+                log.warn("Problem creating baseURI for " + path, mue);
+            }
+        }
+
+        return baseURL;
+    }
+
+    //----------- internal helper to find the entry ------------------------
+
+    /**
+     * Returns a JAR URL to access the named resource within the archive
+     * underlying this class path entry. This is a helper method for the
+     * {@link ClassLoaderResource} instance returned by
+     * {@link #getResource(String)} method.
+     * <p>
+     * This method does not check, whether the named entry actually exists in
+     * the underlying archive.
+     *
+     * @param name The name of the resource for which to create the JAR URL.
+     */
+    protected URL getURL(String name) {
+        try {
+            return URLFactory.createJarURL(session, path, name);
+        } catch (MalformedURLException mue) {
+            log.error("getURL: Cannot create URL for " + name, mue);
+        }
+        return null;
+    }
+
+    /**
+     * Returns an URL to access the underlying archive itself of this class
+     * path entry. The URL returned may be used as the code source for Java
+     * securtiy protection domains. This is a helper method for the
+     * {@link ClassLoaderResource} instance returned by
+     * {@link #getResource(String)} method.
+     *
+     * @return The URL to access the underlying archive.
+     */
+    protected URL getCodeSourceURL() {
+        try {
+            return URLFactory.createURL(session, path);
+        } catch (MalformedURLException mue) {
+            log.warn("getCodeSourceURL: Cannot getURL" + " for " + path, mue);
+        }
+        return null;
+    }
+
+    /**
+     * Returns a <code>JarInputStream</code> from the property.
+     *
+     * @param property The <code>Property</code> containing the archive to
+     *      access.
+     *
+     * @return A valid <code>JarInputStream</code>.
+     *
+     * @throws RepositoryException If an <code>InputStream</code> cannot be
+     *      retrieved from the property.
+     * @throws IOException If the <code>JarInputStream</code> cannot be
+     *      created.
+     */
+    static JarInputStream getJarInputStream(Property property)
+            throws RepositoryException, IOException {
+        return new JarInputStream(property.getStream());
+    }
+
+    /**
+     * Returns the <code>Manifest</code> object of the JAR archive file
+     * underlying this archive class path entry. If no manifest exists in the
+     * JAR file or if the archive is not a JAR file at - e.g. a plain ZIP
+     * file - this method returns <code>null</code>. If an error occurrs
+     * trying to access the manifest, <code>null</code> is also returned. Later
+     * calls to this method, will not try again to read the manifest file,
+     * though.
+     * <p>
+     * This method is synchronized to prevent two threads from trying to access
+     * the manifest at the same time, which might result in false negative
+     * returned.
+     *
+     * @return The manifest contained in the underlying JAR file or
+     *      <code>null</code> if none exists or an error occurrs trying to
+     *      load the manifest.
+     */
+    protected synchronized Manifest getManifest() {
+        if (jarManifest == null && !jarManifestRead) {
+
+            // immediately mark the manifest read, to prevent repeated read
+            // in the case of missing manifest
+            jarManifestRead = true;
+
+            JarInputStream zipIns = null;
+            try {
+                zipIns = new JarInputStream(prop.getStream());
+                jarManifest = zipIns.getManifest();
+            } catch (RepositoryException re) {
+                log.warn("Cannot access JAR file " + getPath(), re);
+            } catch (IOException ioe) {
+                log.warn("Cannot access manifest of JAR file " + getPath(), ioe);
+            } finally {
+                if (zipIns != null) {
+                    try {
+                        zipIns.close();
+                    } catch (IOException ignore) {
+                    }
+                }
+            }
+        }
+
+        return jarManifest;
+    }
+
+    /**
+     * Returns the <code>JarEntry</code> for the path from the
+     * <code>JarInputStream</code> or <code>null</code> if the path cannot
+     * be found in the archive.
+     *
+     * @param zins The <code>JarInputStream</code> to search in.
+     * @param path The path of the <code>JarEntry</code> to return.
+     *
+     * @return The <code>JarEntry</code> for the path or <code>null</code>
+     *      if no such entry can be found.
+     *
+     * @throws IOException if a problem occurrs reading from the stream.
+     */
+    JarEntry findEntry(JarInputStream zins, String path)
+        throws IOException {
+
+        if (entryMap == null) {
+
+            // make sure to not build the list twice
+            synchronized (this) {
+
+                /**
+                 * make sure, we still need to build the list. this
+                 * implementation surely does not cure all problems of the
+                 * double-checked-locking problem, but it surely remmedies
+                 * the main problem where the reference is already written
+                 * to the field before the constructor has finished. Also
+                 * this only assigns the field when the contents has been
+                 * filled.
+                 */
+                if (entryMap == null) {
+
+                    // prepare an empty entry map to be filled
+                    Map tmpEntryMap = new HashMap();
+
+                    try {
+                        // build the name-to-index map
+                        log.debug("findEntry: Building map while searching");
+
+                        JarEntry result = null;
+                        JarEntry entry = zins.getNextJarEntry();
+                        for (int i=0; entry != null; i++) {
+
+                            // add the entry to the map
+                            String name = entry.getName();
+                            Integer entryNumO = new Integer(i);
+                            tmpEntryMap.put(name, entryNumO);
+                            log.debug("findEntry: Entry " + name + " ==> " +
+                                entryNumO);
+
+                            // if we found our entry, keep it to be returned later
+                            if (result == null && path.equals(name)) {
+                                log.debug("findEntry: Found the entry, " +
+                                        "continue indexing");
+                                result = entry;
+                            }
+
+                            // on to the next entry
+                            entry = zins.getNextJarEntry();
+                        }
+                        // invariant: path has the entry found or null
+
+                        // return what we found
+                        log.debug("findEntry: Indexing complete, " +
+                                "returning " + result);
+                        return result;
+
+                    } finally {
+
+                        /**
+                         * assign the finished tmp entryMap to the field now.
+                         * theoretically, this may still be null, which
+                         * is no issue because it will be tried to be
+                         * rebuilt - over and over again, though - by the
+                         * next call to findEntry.
+                         * in the case of build problems, the map be empty
+                         * in which case it will not be rebuilt, which is
+                         * ok, too, given that reading will still yield
+                         * problems.
+                         */
+
+                        entryMap = tmpEntryMap;
+                    }
+
+                }
+            }
+        }
+        // invariant: entryMap is not null, but might be empty
+        // ( in case of problems creating the tmpEntryMap above, e.g.
+        //   OutOfMemoryError, the entryMap might be null, but then we
+        //   are thrown out of the method any way ... this is no issue
+        //   here )
+
+        // map exists, lets try to get via number
+        Number entryNumO = (Number) entryMap.get(path);
+        if (entryNumO == null) {
+            log.debug("findEntry: This archive does not contain " + path);
+            return null;
+        }
+
+        // find the indexed entry
+        log.debug("findEntry: " + path + " is entry #" + entryNumO);
+        int entryNum = entryNumO.intValue();
+        JarEntry entry = zins.getNextJarEntry();
+        while (entryNum > 0 && entry != null) {
+            entry = zins.getNextJarEntry();
+            entryNum--;
+        }
+        return entry;
+    }
+
+    /**
+     * The <code>ArchiveClassPathResource</code> extends the
+     * {@link ClassLoaderResource} with support to extract resources from a
+     * JAR or ZIP archive.
+     *
+     * @author Felix Meschberger
+     * @version $Rev:$, $Date:$
+     */
+    private static class ArchiveClassPathResource extends ClassLoaderResource {
+
+        /**
+         * The JAR/ZIP file entry providing the name, size and modification
+         * time information.
+         */
+        private final JarEntry jarEntry;
+
+        /**
+         * Creates an instance of this resource for the given
+         * {@link ArchiveClassPathEntry} and JAR/ZIP file entry.
+         *
+         * @param pathEntry The {@link ArchiveClassPathEntry} from which this
+         *      resource has been loaded.
+         * @param jarEntry The JAR/ZIP file entry describing this resource.
+         */
+        private ArchiveClassPathResource(ArchiveClassPathEntry pathEntry,
+                JarEntry jarEntry) {
+            super(pathEntry, jarEntry.getName(), pathEntry.getProperty());
+            this.jarEntry = jarEntry;
+        }
+
+        /**
+         * Returns an URL to access this resource.
+         *
+         * @see ArchiveClassPathEntry#getURL(String)
+         */
+        public URL getURL() {
+            return getArchiveClassPathEntry().getURL(getName());
+        }
+
+        /**
+         * Returns an URL identifying the archive from which this resource is
+         * loaded.
+         *
+         * @see ArchiveClassPathEntry#getCodeSourceURL()
+         */
+        public URL getCodeSourceURL() {
+            return getArchiveClassPathEntry().getCodeSourceURL();
+        }
+
+        /**
+         * Returns an <code>InputStream</code> to read the contents of the
+         * resource. Calling this method actually accesses the JAR/ZIP file
+         * and seeks through the file until the entry is found.
+         * <p>
+         * Clients of this method must make sure to close the stream returned
+         * if not used anymore to prevent resource drain.
+         *
+         * @throws RepositoryException If an error occurrs accessing or reading
+         *      the archive.
+         *
+         * @see ArchiveClassPathEntry#findEntry(JarInputStream, String)
+         */
+        public InputStream getInputStream() throws RepositoryException {
+            /**
+             * Cannot reuse the ClassPathEntry instances entry and
+             * JarInputStream, because this is shared and has to be
+             * closed to release the property resource.
+             */
+            JarInputStream zipIns = null;
+            JarEntry entry = null;
+
+            try {
+
+                zipIns = getJarInputStream(getProperty());
+                entry = getArchiveClassPathEntry().findEntry(zipIns, getName());
+                if (entry != null) {
+                    return zipIns;
+                }
+
+                // otherwise
+                log.warn("Cannot find entry " + getName() + " in the archive "
+                    + getClassPathEntry().getPath() + " anymore!");
+                return null;
+
+            } catch (IOException ioe) {
+
+                // log
+                throw new RepositoryException(ioe);
+
+            } finally {
+
+                // if thrown during findEntry(), entry is null but
+                // the stream is open. As we exit by an exception,
+                // the InputStream is not returned and must be
+                // closed to release it.
+
+                if (entry == null && zipIns != null) {
+                    try {
+                        zipIns.close();
+                    } catch (IOException ignored) {
+                    }
+                }
+
+            }
+        }
+
+        /**
+         * Returns the value of the <code>size</code> field of the JAR/ZIP
+         * file entry of this resource. If the size is not known to the entry,
+         * <code>-1</code> may be returned.
+         */
+        public int getContentLength() {
+            return (int) jarEntry.getSize();
+        }
+
+        /**
+         * Returns the path to the property containing the archive or the
+         * path with which the {@link ArchiveClassPathEntry} was created if the
+         * former cannot be retrieved.
+         */
+        public String getPath() {
+            try {
+                return getProperty().getPath();
+            } catch (RepositoryException re) {
+                String archivePath = getClassPathEntry().getPath();
+                log.warn("Cannot access the path of the archive " +
+                        "property below " + archivePath, re);
+                return archivePath;
+            }
+        }
+
+        /**
+         * Returns the value of the <code>time</code> field of the JAR/ZIP
+         * file entry of this resource. If the time is not known to the entry,
+         * <code>-1</code> may be returned.
+         */
+        public long getLastModificationTime() {
+            return jarEntry.getTime();
+        }
+
+        /**
+         * Returns the manifest of the archive from which this resource was
+         * loaded or <code>null</code> if no such manifest exists or an error
+         * occurrs reading the manifest.
+         *
+         * @see ArchiveClassPathEntry#getManifest()
+         */
+        public Manifest getManifest() {
+            return getArchiveClassPathEntry().getManifest();
+        }
+
+        /**
+         * Returns the {@link ArchiveClassPathEntry} from which this resource
+         * was loaded.
+         */
+        protected ArchiveClassPathEntry getArchiveClassPathEntry() {
+            return (ArchiveClassPathEntry) getClassPathEntry();
+        }
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ArchiveClassPathEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ArchiveClassPathEntry.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassLoaderResource.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassLoaderResource.java?rev=358296&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassLoaderResource.java (added)
+++ incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassLoaderResource.java Wed Dec 21 06:13:56 2005
@@ -0,0 +1,401 @@
+/*
+ * 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.classloader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.cert.Certificate;
+import java.util.Date;
+import java.util.jar.Manifest;
+
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.net.URLFactory;
+
+
+/**
+ * The <code>ClassLoaderResource</code> class represents a resource looked up
+ * by the {@link ClassPathEntry}s of the {@link RepositoryClassLoader}. The
+ * class provides transparent access to the resource irrespective of the fact
+ * on whether the resource is contained in a repository property or in an
+ * JAR or ZIP archive.
+ * <p>
+ * This class is extended to implement depending features such as storing
+ * resources in repository properties or JAR or ZIP archives.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date:$
+ */
+class ClassLoaderResource {
+
+    /** default log category */
+    private static final Log log = LogFactory.getLog(ClassLoaderResource.class);
+
+    /**
+     * The class path entry which loaded this class loader resource
+     */
+    private final ClassPathEntry pathEntry;
+
+    /**
+     * The name of this resource.
+     */
+    private final String name;
+
+    /**
+     * The repository property providing the resource's contents. This may be
+     * <code>null</code> if the resource was loaded from a JAR/ZIP archive.
+     */
+    private final Property resProperty;
+
+    /**
+     * The class optionally loaded/defined through this resource.
+     *
+     * @see #getLoadedClass()
+     * @see #setLoadedClass(Class)
+     */
+    private Class loadedClass;
+
+    /**
+     * The time in milliseconds at which this resource has been loaded from
+     * the repository.
+     */
+    private final long loadTime;
+
+    /**
+     * Creates an instance of this class for the class path entry.
+     *
+     * @param pathEntry The {@link ClassPathEntry} of the code source of this
+     *      class loader resource.
+     * @param name The path name of this resource.
+     * @param resProperty The <code>Property</code>providing the content's of
+     *      this resource. This may be <code>null</code> if the resource
+     *      was loaded from an JAR or ZIP archive.
+     */
+    /* package */ ClassLoaderResource(ClassPathEntry pathEntry, String name,
+            Property resProperty) {
+        this.pathEntry = pathEntry;
+        this.name = name;
+        this.resProperty = resProperty;
+        this.loadTime = System.currentTimeMillis();
+    }
+
+    /**
+     * Returns the {@link ClassPathEntry} which loaded this resource.
+     */
+    protected ClassPathEntry getClassPathEntry() {
+        return pathEntry;
+    }
+
+    /**
+     * Returns the name of this resource. This is the name used to find the
+     * resource, for example the class name or the properties file path.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the <code>Property</code> with which this resource is created.
+     */
+    protected Property getProperty() {
+        return resProperty;
+    }
+
+    /**
+     * Returns the time in milliseconds at which this resource has been loaded
+     */
+    protected long getLoadTime() {
+        return loadTime;
+    }
+
+    /**
+     * Returns the URL to access this resource, for example a JCR or a JAR URL.
+     * If the URL cannot be created from the resource data, <code>null</code> is
+     * returned.
+     */
+    public URL getURL() {
+        try {
+            return URLFactory.createURL(getClassPathEntry().session, getPath());
+        } catch (Exception e) {
+            log.warn("getURL: Cannot getURL for " + getPath(), e);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the URL to the code source of this entry. If there is no code
+     * source available, <code>null</code> is returned.
+     * <p>
+     * This base class implementation returns the result of calling
+     * {@link ClassPathEntry#toURL()} on the class path entry from which this
+     * resource was loaded.
+     */
+    public URL getCodeSourceURL() {
+        return getClassPathEntry().toURL();
+    }
+
+    /**
+     * Returns an <code>InputStream</code> to read from the resource.
+     * <p>
+     * This base class implementation returns the result of calling the
+     * <code>getStream()</code> method on the resource's property or
+     * <code>null</code> if the property is not set.
+     */
+    public InputStream getInputStream() throws RepositoryException {
+        return (getProperty() != null) ? getProperty().getStream() : null;
+    }
+
+    /**
+     * Returns the size of the resource or -1 if the size cannot be found out.
+     * <p>
+     * This base class implementation returns the result of calling the
+     * <code>getLength()</code> method on the resource's property or -1 if
+     * the property is not set.
+     *
+     * @throws RepositoryException If an error occurrs trying to find the length
+     *      of the property.
+     */
+    public int getContentLength() throws RepositoryException {
+        return (getProperty() != null) ? (int) getProperty().getLength() : -1;
+    }
+
+    /**
+     * Returns the path of the property containing the resource.
+     * <p>
+     * This base class implementation returns the absolute path of the
+     * resource's property. If the property is not set or if an error occurrs
+     * accesing the property's path, the concatentation of the class path
+     * entry's path and the resource's name is returned.
+     */
+    public String getPath() {
+        if (getProperty() != null) {
+            try {
+                return getProperty().getPath();
+            } catch (RepositoryException re) {
+                // fallback
+                log.warn("getPath: Cannot retrieve path of entry " + getName(),
+                    re);
+            }
+        }
+
+        // fallback if no resource property or an error accessing the path of
+        // the property
+        return getClassPathEntry().getPath() + getName();
+    }
+
+    /**
+     * Returns the time of the the last modification of the resource or -1 if
+     * the last modification time cannot be evaluated.
+     * <p>
+     * This base class implementation returns the result of calling the
+     * {@link Util#getLastModificationTime(Property)} method on the resource's
+     * property if not <code>null</code>. In case of an error or if the
+     * property is <code>null</code>, -1 is returned.
+     */
+    public long getLastModificationTime() {
+        if (getProperty() != null) {
+            try {
+                return Util.getLastModificationTime(getProperty());
+            } catch (RepositoryException re) {
+                log.info("getLastModificationTime of resource property", re);
+            }
+        }
+
+        // cannot find the resource modification time, use epoch
+        return -1;
+    }
+
+    /**
+     * Returns the resource as an array of bytes
+     */
+    public byte[] getBytes() throws IOException, RepositoryException {
+        InputStream in = null;
+        byte[] buf = null;
+
+        log.debug("getBytes");
+
+        try {
+            in = getInputStream();
+            log.debug("getInputStream() returned " + in);
+
+            int length = getContentLength();
+            log.debug("getContentLength() returned " + String.valueOf(length));
+
+            if (length >= 0) {
+
+                buf = new byte[length];
+                for (int read; length > 0; length -= read) {
+                    read = in.read(buf, buf.length - length, length);
+                    if (read == -1) {
+                        throw new IOException("unexpected EOF");
+                    }
+                }
+
+            } else {
+
+                buf = new byte[1024];
+                int count = 0;
+                int read;
+
+                // read enlarging buffer
+                while ((read = in.read(buf, count, buf.length - count)) != -1) {
+                    count += read;
+                    if (count >= buf.length) {
+                        byte buf1[] = new byte[count * 2];
+                        System.arraycopy(buf, 0, buf1, 0, count);
+                        buf = buf1;
+                    }
+                }
+
+                // resize buffer if too big
+                if (count != buf.length) {
+                    byte buf1[] = new byte[count];
+                    System.arraycopy(buf, 0, buf1, 0, count);
+                    buf = buf1;
+                }
+
+            }
+
+        } finally {
+
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException ignore) {
+                }
+            }
+
+        }
+
+        return buf;
+    }
+
+    /**
+     * Returns the manifest from the jar file for this class resource. If this
+     * resource is not from a jar file, the method returns <code>null</code>,
+     * which is what the default implementation does.
+     */
+    public Manifest getManifest() {
+        return null;
+    }
+
+    /**
+     * Returns the certificates from the jar file for this class resource. If
+     * this resource is not from a jar file, the method returns
+     * <code>null</code>, which is what the default implementation does.
+     */
+    public Certificate[] getCertificates() {
+        return null;
+    }
+
+    /**
+     * Returns the <code>Property</code> which is used to check whether this
+     * resource is expired or not.
+     * <p>
+     * This base class method returns the same property as returned by the
+     * {@link #getProperty()} method. This method may be overwritten by
+     * implementations as appropriate.
+     *
+     * @see #isExpired()
+     */
+    protected Property getExpiryProperty() {
+        return getProperty();
+    }
+
+    /**
+     * Returns <code>true</code> if the last modification date of the expiry
+     * property of this resource is loaded is later than the time at which this
+     * resource has been loaded. If the last modification time of the expiry
+     * property cannot be calculated or if an error occurrs checking the expiry
+     * propertiy's last modification time, <code>true</code> is returned.
+     */
+    public boolean isExpired() {
+        try {
+            // creation time of version if loaded now
+            long currentPropTime = 0;
+            Property prop = getExpiryProperty();
+            if (prop != null) {
+                currentPropTime = Util.getLastModificationTime(prop);
+            }
+
+            // creation time of version currently loaded
+            long loadTime = getLoadTime();
+
+            // expire if a new version would be loaded
+            boolean exp = currentPropTime > loadTime;
+            if (exp && log.isDebugEnabled()) {
+                log.debug("expireResource: Resource created " +
+                    new Date(loadTime) + " superceded by version created " +
+                    new Date(currentPropTime));
+            }
+
+            // return the result of checking
+            return exp;
+        } catch (RepositoryException re) {
+            log.debug("expireResource: Cannot get current version for " +
+                toString() + ", will expire: " + re);
+            return true;
+        }
+    }
+
+    /**
+     * Returns the class which was loaded through this resource. It is expected
+     * that the class loader sets the class which was loaded through this
+     * resource by calling the {@link #setLoadedClass(Class)} method. If this
+     * class was not used to load a class or if the class loader failed to
+     * set the class loaded through this resoource, this method will return
+     * <code>null</code>.
+     *
+     * @return The class loaded through this resource, which may be
+     *      <code>null</code> if this resource was never used to load a class
+     *      or if the loader failed to set class through the
+     *      {@link #setLoadedClass(Class)} method.
+     *
+     * @see #setLoadedClass(Class)
+     */
+    public Class getLoadedClass() {
+        return loadedClass;
+    }
+
+    /**
+     * Sets the class which was loaded through this resource. This method does
+     * not check, whether it is plausible that this class was actually loaded
+     * from this resource, nor does this method check whether the class object
+     * is <code>null</code> or not.
+     *
+     * @param loadedClass The class to be loaded.
+     */
+    public void setLoadedClass(Class loadedClass) {
+        this.loadedClass = loadedClass;
+    }
+
+    /**
+     * Returns the <code>String</code> representation of this resource.
+     */
+    public String toString() {
+        StringBuffer buf = new StringBuffer(getClass().getName());
+        buf.append(": path=");
+        buf.append(getPath());
+        buf.append(", name=");
+        buf.append(getName());
+        return buf.toString();
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassLoaderResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassLoaderResource.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassPathEntry.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassPathEntry.java?rev=358296&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassPathEntry.java (added)
+++ incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassPathEntry.java Wed Dec 21 06:13:56 2005
@@ -0,0 +1,272 @@
+/*
+ * 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.classloader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessControlException;
+import java.util.jar.JarException;
+import java.util.jar.JarInputStream;
+
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.net.URLFactory;
+
+/**
+ * The <code>ClassPathEntry</code> class encapsulates entries in the class path
+ * of the {@link DynamicRepositoryClassLoader}. The main task is to retrieve
+ * {@link ClassLoaderResource} instances for classes or resources to load from it.
+ * <p>
+ * This implementation is not currently integrated with Java security. That is
+ * protection domains and security managers are not supported yet.
+ * <p>
+ * This class is not intended to be subclassed or instantiated by clients.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date:$
+ */
+abstract class ClassPathEntry {
+
+    /** default logging */
+    private static final Log log = LogFactory.getLog(ClassPathEntry.class);
+
+    /** The session assigned to this class path entry */
+    protected final Session session;
+
+    /** The path to the item of this class path entry */
+    protected final String path;
+
+    /** The base URL for the class path entry to later construct resource URLs */
+    protected URL baseURL;
+
+    //---------- construction --------------------------------------------------
+
+    /**
+     * Creates an instance of the <code>ClassPathEntry</code> assigning the
+     * session and path.
+     *
+     * @param session The <code>Session</code> to access the Repository.
+     * @param path The path of the class path entry, this is either the
+     *      path of a node containing a jar archive or is the path
+     *      of the root of a hierarchy to look up resources in.
+     */
+    protected ClassPathEntry(Session session, String path) {
+        this.path = path;
+        this.session = session;
+    }
+
+    /**
+     * Clones this instance of the <code>ClassPathEntry</code> setting the
+     * path and session to the same value as the base instance.
+     * <p>
+     * Note that this constructor does not duplicate the session from the base
+     * instance.
+     *
+     * @param base The <code>ClassPathEntry</code> from which to copy the path
+     *      and the session.
+     */
+    protected ClassPathEntry(ClassPathEntry base) {
+        this.path = base.path;
+        this.session = base.session;
+        this.baseURL = base.baseURL;
+    }
+
+    /**
+     * Returns an instance of the <code>ClassPathEntry</code> class. This
+     * instance will be a subclass correctly handling the type (directory or
+     * jar archive) of class path entry is to be created.
+     * <p>
+     * If the path given has a trailing slash, it is taken as a directory root
+     * else the path is first tested, whether it contains an archive. If not
+     * the path is treated as a directory.
+     *
+     * @param session The <code>Session</code> to access the Repository.
+     * @param path The path of the class path entry, this is either the
+     *      path of a node containing a jar archive or is the path
+     *      of the root of a hierharchy to look up resources in.
+     *
+     * @return An initialized <code>ClassPathEntry</code> instance for the
+     *      path or <code>null</code> if an error occurred creating the
+     *      instance.
+     */
+    static ClassPathEntry getInstance(Session session, String path) {
+
+        // check we can access the path, don't care about content now
+        try {
+            session.checkPermission(path, "read");
+        } catch (AccessControlException ace) {
+            log.warn("getInstance: Access denied reading from " + path +
+                ", ignoring entry");
+            return null;
+        } catch (RepositoryException re) {
+            log.error("getInstance: Cannot check permission to " + path, re);
+        }
+
+        // only check for archive if no trailing slash in path
+        if (!path.endsWith("/")) {
+            InputStream is = null;
+            JarInputStream zip = null;
+            try {
+
+                Property prop = Util.getProperty(session.getItem(path));
+                if (prop != null) {
+
+                    is = prop.getStream();
+                    zip = new JarInputStream(is);
+                    if (zip.getNextJarEntry() != null /* && zip.read() != -1 */ ) {
+                        // use the expanding jar support if can expand
+                        if (ExpandingArchiveClassPathEntry.canExpandArchives(session)) {
+                            return new ExpandingArchiveClassPathEntry(prop, path);
+                        }
+
+                        // otherwise use the non-expanding
+                        return new ArchiveClassPathEntry(prop, path);
+                    }
+
+                    log.debug("getInstance: " + path + " might not be a jar " +
+                            "archive, using as directory");
+                } else {
+                    log.debug("getInstance: " + path + " does not resolve" +
+                            " to a property, using as directory");
+                }
+
+            } catch (ItemNotFoundException infe) {
+
+                // how to path ?
+                // thrown from
+                //   - Node.getPrimaryItem
+                //   -
+
+            } catch (PathNotFoundException pnfe) {
+
+                // how to path ?
+                // thrown from
+                //   - session.getItem
+                //   -
+
+            } catch (RepositoryException re) {
+
+                log.debug("getInstance: " + path + " cannot be read from, " +
+                        "using as directory");
+
+            } catch (JarException ze) {
+
+                log.debug("getInstance: " + path + " does not contain an " +
+                        "archive, using as directory");
+
+            } catch (IOException ioe) {
+
+                log.debug("getInstance: " + path + " problem reading from " +
+                        "the archive, using as directory");
+
+            } finally {
+                if (zip != null) {
+                    try {
+                        zip.close();
+                    } catch (IOException ignored) {}
+                } else if (is != null) {
+                    try {
+                        is.close();
+                    } catch (IOException ignored) {}
+                }
+            }
+            // assume the path designates a directory
+
+            // append trailing slash now
+            path += "/";
+        }
+
+        // we assume a directory class path entry, but we might have to check
+        // whether the path refers to a node or not. On the other hande, this
+        // class path entry will not be usable anyway if not, user beware :-)
+
+        return new DirectoryClassPathEntry(session, path);
+    }
+
+    /**
+     * Returns the path on which this <code>ClassPathEntry</code> is based.
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * Returns this <code>ClassPathEntry</code> represented as an URL to be
+     * used in a list of URLs to further work on. If there is a problem creating
+     * the URL for this instance, <code>null</code> is returned instead.
+     */
+    public URL toURL() {
+        if (baseURL == null) {
+            try {
+                baseURL = URLFactory.createURL(session, path);
+            } catch (MalformedURLException mue) {
+                log.warn("DirectoryClassPathEntry: Creating baseURl for " +
+                    path, mue);
+            }
+        }
+
+        return baseURL;
+    }
+
+    /**
+     * Returns a <code>ClassPathEntry</code> with the same configuration as
+     * this <code>ClassPathEntry</code>.
+     * <p>
+     * The returned object may be but need not be a new instance. If the original
+     * implementation is an immutable class, the instance returned may well
+     * be the same as this.
+     */
+    abstract ClassPathEntry copy();
+
+    /**
+     * Searches for the named resource. The name is looked up as is, it is not
+     * further modified such as appended with ".class" or made relative. That
+     * is callers must make sure, that (1) this name is the full name of the
+     * resource to find and that (2) it is a relative name, that is it should
+     * not have a leading slash.
+     * <p>
+     * An example of a class to find would be : <code>com/day/test/Tester.class</code>
+     * which is converted from the generally used value <code>com.day.test.Tester</code>
+     * by the caller.
+     *
+     * @param name The name of the resource to find.
+     */
+    public abstract ClassLoaderResource getResource(String name);
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString() {
+        StringBuffer buf = new StringBuffer(super.toString());
+        buf.append(": path: ");
+        buf.append(path);
+        buf.append(", user: ");
+        buf.append(session.getUserID());
+        return buf.toString();
+    }
+
+    //----------- internal helper ----------------------------------------------
+
+}

Propchange: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassPathEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/ClassPathEntry.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DirectoryClassPathEntry.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DirectoryClassPathEntry.java?rev=358296&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DirectoryClassPathEntry.java (added)
+++ incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DirectoryClassPathEntry.java Wed Dec 21 06:13:56 2005
@@ -0,0 +1,111 @@
+/*
+ * 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.classloader;
+
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * The <code>DirectoryClassPathEntry</code> implements the
+ * {@link ClassPathEntry} abstract class with support for directory like
+ * class path access. The path used to construct the instance is the
+ * root path of a page structure finally containing the classes and
+ * resources.
+ *
+ * @author Felix Meschberger
+ * @version $Rev:$, $Date:$
+ */
+class DirectoryClassPathEntry extends ClassPathEntry {
+
+    /** Default log */
+    private static final Log log =
+        LogFactory.getLog(DirectoryClassPathEntry.class);
+
+    /**
+     * Creates an instance of the <code>DirectoryClassPathEntry</code> class.
+     * <p>
+     * The path given is expected to have a trailing slash character else
+     * results will not be as expected when getting resources.
+     *
+     * @param session The <code>Ticket</code> to access the ContentBus.
+     * @param path The path of the class path entry, which is the path
+     *      of the root of a hierarchy to look up resources in.
+     */
+    DirectoryClassPathEntry(Session ticket, String handle) {
+        super(ticket, handle);
+    }
+
+    /**
+     * Returns a {@link ClassLoaderResource} for the named resource if it
+     * can befound below this directory root identified by the path given
+     * at construction time. Note that if the page would exist but does
+     * either not contain content or is not readable by the current session,
+     * no resource is returned.
+     *
+     * @param name The name of the resource to return. If the resource would
+     *      be a class the name must already be modified to denote a valid
+     *      path, that is dots replaced by dashes and the <code>.class</code>
+     *      extension attached.
+     *
+     * @return The {@link ClassLoaderResource} identified by the name or
+     *      <code>null</code> if no resource is found for that name.
+     */
+    public ClassLoaderResource getResource(final String name) {
+
+        try {
+            final Property prop = Util.getProperty(session.getItem(path + name));
+            if (prop != null) {
+                return new ClassLoaderResource(this, name, prop);
+            }
+
+            log.debug("getResource: resource " + name +
+                " not found below " + path);
+
+        } catch (PathNotFoundException pnfe) {
+
+            log.info("getResource: Classpath entry " + path +
+                " does not have resource " + name);
+
+        } catch (RepositoryException cbe) {
+
+            log.warn("getResource: problem accessing the resource " + name +
+                " below " + path + ": " + cbe);
+
+        }
+        // invariant : no page or problem accessing the page
+
+        return null;
+    }
+
+    /**
+     * Returns a <code>ClassPathEntry</code> with the same configuration as
+     * this <code>ClassPathEntry</code>.
+     * <p>
+     * Becase the <code>DirectoryClassPathEntry</code> class does not have
+     * internal state, this method returns this instance to be used as
+     * the "copy".
+     */
+    ClassPathEntry copy() {
+        return this;
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DirectoryClassPathEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/jackrabbit/trunk/contrib/classloader/src/main/java/org/apache/jackrabbit/classloader/DirectoryClassPathEntry.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url



Mime
View raw message