You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2005/05/11 16:43:03 UTC
svn commit: r169640 - in /cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr:
AbstractRepository.java JNDIRepository.java JackrabbitRepository.java
source/JCRNodeSource.java source/JCRSourceFactory.java
Author: sylvain
Date: Wed May 11 07:43:02 2005
New Revision: 169640
URL: http://svn.apache.org/viewcvs?rev=169640&view=rev
Log:
Fix a few bugs, make repositories and source factory threadsafe, expose some methods for subclassing
Added:
cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JNDIRepository.java (with props)
Modified:
cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/AbstractRepository.java
cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JackrabbitRepository.java
cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRNodeSource.java
cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRSourceFactory.java
Modified: cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/AbstractRepository.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/AbstractRepository.java?rev=169640&r1=169639&r2=169640&view=diff
==============================================================================
--- cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/AbstractRepository.java (original)
+++ cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/AbstractRepository.java Wed May 11 07:43:02 2005
@@ -35,6 +35,7 @@
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
// import org.apache.cocoon.components.variables.VariableResolver;
// import org.apache.cocoon.components.variables.VariableResolverFactory;
import org.apache.cocoon.components.ContextHelper;
@@ -73,7 +74,7 @@
*
* @version $Id$
*/
-public class AbstractRepository implements Repository, Contextualizable, Serviceable, Configurable, Disposable {
+public class AbstractRepository implements Repository, ThreadSafe, Contextualizable, Serviceable, Configurable, Disposable {
// TODO: on login(), keep the JCR Session in the Environment Session, this
// will improve performances.
Added: cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JNDIRepository.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JNDIRepository.java?rev=169640&view=auto
==============================================================================
--- cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JNDIRepository.java (added)
+++ cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JNDIRepository.java Wed May 11 07:43:02 2005
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.jcr;
+
+import javax.jcr.Repository;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+public class JNDIRepository extends AbstractRepository {
+
+ public void configure(Configuration config) throws ConfigurationException {
+ super.configure(config);
+ Configuration rsrcConfig = config.getChild("jndi-resource");
+ String name = rsrcConfig.getAttribute("name");
+
+ try {
+ InitialContext ctx = new InitialContext();
+ this.delegate = (Repository)ctx.lookup(name);
+ } catch (NamingException e) {
+ throw new ConfigurationException("Cannot lookup JNDI entry '" + name + "'", e);
+ }
+ }
+}
Propchange: cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JNDIRepository.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JNDIRepository.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JackrabbitRepository.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JackrabbitRepository.java?rev=169640&r1=169639&r2=169640&view=diff
==============================================================================
--- cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JackrabbitRepository.java (original)
+++ cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/JackrabbitRepository.java Wed May 11 07:43:02 2005
@@ -15,7 +15,6 @@
*/
package org.apache.cocoon.jcr;
-import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.cocoon.components.source.SourceUtil;
@@ -49,7 +48,7 @@
* @see AbstractRepository
* @version $Id$
*/
-public class JackrabbitRepository extends AbstractRepository implements Configurable {
+public class JackrabbitRepository extends AbstractRepository {
public void configure(Configuration config) throws ConfigurationException {
Modified: cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRNodeSource.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRNodeSource.java?rev=169640&r1=169639&r2=169640&view=diff
==============================================================================
--- cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRNodeSource.java (original)
+++ cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRNodeSource.java Wed May 11 07:43:02 2005
@@ -84,7 +84,7 @@
}
}
- protected JCRNodeSource(JCRNodeSource parent, Node node) throws SourceException {
+ public JCRNodeSource(JCRNodeSource parent, Node node) throws SourceException {
this.factory = parent.factory;
this.session = parent.session;
this.node = node;
@@ -116,6 +116,15 @@
public Node getNode() {
return this.node;
}
+
+ /**
+ * Returns the path within the repository this source points to.
+ *
+ * @return the path
+ */
+ public String getPath() {
+ return this.path;
+ }
/**
* Returns the JCR <code>Session</code> used by this source.
@@ -212,6 +221,9 @@
* @see org.apache.excalibur.source.Source#getValidity()
*/
public SourceValidity getValidity() {
+ if (!exists()) {
+ return null;
+ }
try {
Property prop = this.factory.getValidityProperty(this.node);
return prop == null ? null : new JCRNodeSourceValidity(prop.getValue());
@@ -235,6 +247,9 @@
* @see org.apache.excalibur.source.Source#getMimeType()
*/
public String getMimeType() {
+ if (!exists()) {
+ return null;
+ }
try {
Property prop = this.factory.getMimeTypeProperty(this.node);
if (prop == null) {
@@ -254,7 +269,7 @@
* @see org.apache.excalibur.source.Source#getContentLength()
*/
public long getContentLength() {
- if (this.node == null) {
+ if (!exists()) {
return -1;
}
try {
@@ -271,6 +286,9 @@
* @see org.apache.excalibur.source.Source#getLastModified()
*/
public long getLastModified() {
+ if (!exists()) {
+ return 0;
+ }
try {
Property prop = this.factory.getLastModifiedDateProperty(this.node);
return prop == null ? 0 : prop.getDate().getTimeInMillis();
@@ -308,7 +326,7 @@
}
while (nodes.hasNext()) {
- children.add(new JCRNodeSource(this, nodes.nextNode()));
+ children.add(this.factory.createSource(this, nodes.nextNode()));
}
return children;
}
@@ -316,7 +334,7 @@
public Source getChild(String name) throws SourceException {
if (this.isCollection()) {
- return new JCRNodeSource(this.factory, this.session, getChildPath(this.path, name));
+ return this.factory.createSource(this.session, getChildPath(this.path, name));
} else {
throw new SourceException("Not a collection: " + getURI());
}
@@ -334,7 +352,7 @@
int lastPos = this.path.lastIndexOf('/');
String parentPath = lastPos == 0 ? "/" : this.path.substring(0, lastPos);
- return new JCRNodeSource(this.factory, this.session, parentPath);
+ return this.factory.createSource(this.session, parentPath);
}
// =============================================================================================
Modified: cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRSourceFactory.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRSourceFactory.java?rev=169640&r1=169639&r2=169640&view=diff
==============================================================================
--- cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRSourceFactory.java (original)
+++ cocoon/blocks/jcr/trunk/java/org/apache/cocoon/jcr/source/JCRSourceFactory.java Wed May 11 07:43:02 2005
@@ -27,12 +27,14 @@
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
import org.apache.excalibur.source.SourceFactory;
@@ -106,19 +108,19 @@
*
* @version $Id$
*/
-public class JCRSourceFactory implements SourceFactory, Configurable, Serviceable {
+public class JCRSourceFactory implements ThreadSafe, SourceFactory, Configurable, Serviceable {
- static class NodeTypeInfo {
+ protected static class NodeTypeInfo {
// Empty base class
}
- static class FolderTypeInfo extends NodeTypeInfo {
+ protected static class FolderTypeInfo extends NodeTypeInfo {
public String newFileType;
public String newFolderType;
}
- static class FileTypeInfo extends NodeTypeInfo {
+ protected static class FileTypeInfo extends NodeTypeInfo {
public String contentPath;
public String contentType;
@@ -126,7 +128,7 @@
public String contentRef;
}
- static class ContentTypeInfo extends NodeTypeInfo {
+ protected static class ContentTypeInfo extends NodeTypeInfo {
public String contentProp;
public String mimeTypeProp;
@@ -139,23 +141,24 @@
/**
* The repository we use
*/
- private Repository repo;
+ protected Repository repo;
/**
* Scheme, lazily computed at the first call to getSource()
*/
- private String scheme;
+ protected String scheme;
/**
* The NodeTypeInfo for each of the types described in the configuration
*/
- private Map typeInfos;
+ protected Map typeInfos;
- private ServiceManager manager;
+ protected ServiceManager manager;
public void service(ServiceManager manager) throws ServiceException {
this.manager = manager;
- this.repo = (Repository) this.manager.lookup(Repository.class.getName());
+ // this.repo is lazily initialized to avoid a circular dependency between SourceResolver
+ // and JackrabbitRepository that leads to a StackOverflowError at initialization time
}
public void configure(Configuration config) throws ConfigurationException {
@@ -202,6 +205,16 @@
}
}
+
+ protected void lazyInit() {
+ if (this.repo == null) {
+ try {
+ this.repo = (Repository)manager.lookup(Repository.class.getName());
+ } catch (Exception e) {
+ throw new CascadingRuntimeException("Cannot lookup repository", e);
+ }
+ }
+ }
/*
* (non-Javadoc)
@@ -210,6 +223,7 @@
* java.util.Map)
*/
public Source getSource(String uri, Map parameters) throws IOException, MalformedURLException {
+ lazyInit();
if (this.scheme == null) {
this.scheme = SourceUtil.getScheme(uri);
@@ -240,7 +254,7 @@
}
}
- return new JCRNodeSource(this, session, path);
+ return createSource(session, path);
}
/*
@@ -252,7 +266,7 @@
// nothing
}
- String getScheme() {
+ public String getScheme() {
return this.scheme;
}
@@ -263,7 +277,7 @@
* @return the type info
* @throws RepositoryException if node type couldn't be accessed or if no type info is found
*/
- NodeTypeInfo getTypeInfo(Node node) throws RepositoryException {
+ public NodeTypeInfo getTypeInfo(Node node) throws RepositoryException {
String typeName = node.getPrimaryNodeType().getName();
NodeTypeInfo result = (NodeTypeInfo) this.typeInfos.get(typeName);
if (result == null) {
@@ -280,7 +294,7 @@
* @return the type info
* @throws RepositoryException if no type info is found
*/
- NodeTypeInfo getTypeInfo(String typeName) throws RepositoryException {
+ public NodeTypeInfo getTypeInfo(String typeName) throws RepositoryException {
NodeTypeInfo result = (NodeTypeInfo) this.typeInfos.get(typeName);
if (result == null) {
// TODO: build a NodeTypeInfo using introspection
@@ -297,7 +311,7 @@
* @return the content node
* @throws RepositoryException if some error occurs, or if the given node isn't a file node or a content node
*/
- Node getContentNode(Node node) throws RepositoryException {
+ public Node getContentNode(Node node) throws RepositoryException {
NodeTypeInfo info = getTypeInfo(node);
if (info instanceof ContentTypeInfo) {
@@ -318,6 +332,30 @@
throw new RepositoryException("Can't get content node for folder node at " + node.getPath());
}
}
+
+ /**
+ * Creates a new source given its parent and its node
+ *
+ * @param parent the parent
+ * @param node the node
+ * @return a new source
+ * @throws SourceException
+ */
+ public JCRNodeSource createSource(JCRNodeSource parent, Node node) throws SourceException {
+ return new JCRNodeSource(parent, node);
+ }
+
+ /**
+ * Creates a new source given a session and a path
+ *
+ * @param session the session
+ * @param path the absolute path
+ * @return a new source
+ * @throws SourceException
+ */
+ public JCRNodeSource createSource(Session session, String path) throws SourceException {
+ return new JCRNodeSource(this, session, path);
+ }
/**
* Create a child file node in a folder node.
@@ -327,7 +365,7 @@
* @return the newly created child node
* @throws RepositoryException if some error occurs
*/
- Node createFileNode(Node folderNode, String name) throws RepositoryException {
+ public Node createFileNode(Node folderNode, String name) throws RepositoryException {
NodeTypeInfo info = getTypeInfo(folderNode);
if (!(info instanceof FolderTypeInfo)) {
throw new RepositoryException("Node type " + folderNode.getPrimaryNodeType().getName() + " is not a folder type");
@@ -344,7 +382,7 @@
* @return the content node for this file node
* @throws RepositoryException if some error occurs
*/
- Node createContentNode(Node fileNode) throws RepositoryException {
+ public Node createContentNode(Node fileNode) throws RepositoryException {
NodeTypeInfo info = getTypeInfo(fileNode);
if (!(info instanceof FileTypeInfo)) {
@@ -364,7 +402,7 @@
* @return the content property
* @throws RepositoryException if some error occurs
*/
- Property getContentProperty(Node node) throws RepositoryException {
+ public Property getContentProperty(Node node) throws RepositoryException {
Node contentNode = getContentNode(node);
ContentTypeInfo info = (ContentTypeInfo) getTypeInfo(contentNode);
return contentNode.getProperty(info.contentProp);
@@ -377,7 +415,7 @@
* @return the mime-type property, or <code>null</code> if no such property exists
* @throws RepositoryException if some error occurs
*/
- Property getMimeTypeProperty(Node node) throws RepositoryException {
+ public Property getMimeTypeProperty(Node node) throws RepositoryException {
Node contentNode = getContentNode(node);
ContentTypeInfo info = (ContentTypeInfo) getTypeInfo(contentNode);
@@ -396,7 +434,7 @@
* @return the lastmodified property, or <code>null</code> if no such property exists
* @throws RepositoryException if some error occurs
*/
- Property getLastModifiedDateProperty(Node node) throws RepositoryException {
+ public Property getLastModifiedDateProperty(Node node) throws RepositoryException {
Node contentNode = getContentNode(node);
ContentTypeInfo info = (ContentTypeInfo) getTypeInfo(contentNode);
@@ -415,7 +453,7 @@
* @return the validity property, or <code>null</code> if no such property exists
* @throws RepositoryException if some error occurs
*/
- Property getValidityProperty(Node node) throws RepositoryException {
+ public Property getValidityProperty(Node node) throws RepositoryException {
Node contentNode = getContentNode(node);
ContentTypeInfo info = (ContentTypeInfo) getTypeInfo(contentNode);
@@ -434,7 +472,7 @@
* @return <code>true</code> if it's a collection
* @throws RepositoryException if some error occurs
*/
- boolean isCollection(Node node) throws RepositoryException {
+ public boolean isCollection(Node node) throws RepositoryException {
return getTypeInfo(node) instanceof FolderTypeInfo;
}
@@ -445,7 +483,7 @@
* @return the child folder node type
* @throws RepositoryException if some error occurs
*/
- String getFolderNodeType(Node folderNode) throws RepositoryException {
+ public String getFolderNodeType(Node folderNode) throws RepositoryException {
FolderTypeInfo info = (FolderTypeInfo) getTypeInfo(folderNode);
return info.newFolderType;
}