* This class may not be extended or instantiated, it just contains static
* utility methods.
- *
- * @author Felix Meschberger
*/
public class Util {
@@ -44,45 +42,85 @@
private static final Logger log = LoggerFactory.getLogger(Util.class);
/** Private constructor to not instantiate */
- private Util() {}
+ private Util() {
+ }
/**
- * Resolves the given item to a Property. If the
- * item is a node, the getPrimaryItem method is
- * called repeatedly until a property is returned or until no more primary
- * item is available. If the resulting property is a multivalue property,
- * null is returned. Otherwise if the resulting property is
- * a REFERENCE property, the node referred to is retrieved
- * and this method is called recursively with the node. Otherwise, the
- * resulting property is returned.
- *
+ * Resolves the given item to a Property from
+ * which contents can be read.
+ *

+ * The following mechanism is used to derive the contents:
+ *

+ *

If the item is a property, this property is used

+ *

If the item is a node, three steps are tested:
+ *
+ *

If the node has a jcr:content child node, use that
+ * child node in the next steps. Otherwise continue with the node.

+ *

Check for a jcr:data property and use that property
+ * if existing.

+ *

Otherwise call getPrimaryItem method repeatedly until
+ * a property is returned or until no more primary item is available.

+ *
+ *

+ * If no property can be resolved using the above algorithm or if the
+ * resulting property is a multivalue property, null is
+ * returned. Otherwise if the resulting property is a REFERENCE
+ * property, the node referred to is retrieved and this method is called
+ * recursively with the node. Otherwise, the resulting property is returned.
+ *
* @param item The Item to resolve to a Property.
- *
- * @return The resolved Property or null if the
- * resolved property is a multi-valued property.
- *
- * @throws ItemNotFoundException If the item is a node which
- * cannot be resolved to a property through (repeated) calls to
- * Node.getPrimaryItem.
+ * @return The resolved Property or null if
+ * the resolved property is a multi-valued property or the
+ * item is a node which cannot be resolved to a data
+ * property.
* @throws ValueFormatException If the item resolves to a
- * single-valued REFERENCE type property which cannot
- * be resolved to the node referred to.
+ * single-valued REFERENCE type property which
+ * cannot be resolved to the node referred to.
* @throws RepositoryException if another error occurrs accessing the
- * repository.
+ * repository.
*/
- public static Property getProperty(Item item)
- throws ItemNotFoundException, ValueFormatException,
+ public static Property getProperty(Item item) throws ValueFormatException,
RepositoryException {
- // if the item is a node, get its primary item until either
- // no primary item exists any more or an ItemNotFoundException is thrown
- while (item.isNode()) {
- item = ((Node) item).getPrimaryItem();
+ Property prop;
+ if (item.isNode()) {
+
+ // check whether the node has a jcr:content node (e.g. nt:file)
+ Node node = (Node) item;
+ if (node.hasNode("jcr:content")) {
+ node = node.getNode("jcr:content");
+ }
+
+ // if the node has a jcr:data property, use that property
+ if (node.hasProperty("jcr:data")) {
+
+ prop = node.getProperty("jcr:data");
+
+ } else {
+
+ // otherwise try to follow default item trail
+ try {
+ item = node.getPrimaryItem();
+ while (item.isNode()) {
+ item = ((Node) item).getPrimaryItem();
+ }
+ prop = (Property) item;
+ } catch (ItemNotFoundException infe) {
+ // we don't actually care, but log for completeness
+ log.debug("getProperty: No primary items for "
+ + node.getPath(), infe);
+ return null;
+ }
+ }
+
+ } else {
+
+ prop = (Property) item;
+
}
// we get here with a property - otherwise an exception has already
// been thrown
- Property prop = (Property) item;
if (prop.getDefinition().isMultiple()) {
log.error("{} is a multivalue property", prop.getPath());
return null;
@@ -97,34 +135,29 @@
}
/**
- * Returns the last modification time of the property. If the property's
- * parent node is a nt:resource the long value
- * of the jcr:lastModified property of the parent node is
- * returned. Otherwise the current system time is returned.
- *
- * @param prop The property for which to return the last modification
- * time.
- *
- * @return The last modification time of the resource or the current time
- * if the property is not a child of an nt:resource node.
- *
+ * Returns the last modification time of the property, which is the long
+ * value of the jcr:lastModified property of the parent node
+ * of prop. If the parent node does not have a
+ * jcr:lastModified property the current system time is
+ * returned.
+ *
+ * @param prop The property for which to return the last modification time.
+ * @return The last modification time of the resource or the current time if
+ * the parent node of the property does not have a
+ * jcr:lastModified property.
* @throws ItemNotFoundException If the parent node of the property cannot
- * be retrieved.
- * @throws PathNotFoundException If the "jcr:lastModified" property of the
- * parent node cannot be retrieved. This exception is unlikely in a
- * correctly configured repository as the jcr:lastModified property
- * has to be present in a node of type nt:resource.
+ * be retrieved.
* @throws AccessDeniedException If (read) access to the parent node is
- * denied.
+ * denied.
* @throws RepositoryException If any other error occurrs accessing the
- * repository to retrieve the last modification time.
+ * repository to retrieve the last modification time.
*/
public static long getLastModificationTime(Property prop)
throws ItemNotFoundException, PathNotFoundException,
AccessDeniedException, RepositoryException {
Node parent = prop.getParent();
- if (parent.isNodeType("nt:resource")) {
+ if (parent.hasProperty("jcr:lastModified")) {
return parent.getProperty("jcr:lastModified").getLong();
}
Modified: jackrabbit/branches/1.4/jackrabbit-classloader/src/main/java/org/apache/jackrabbit/net/JCRURLConnection.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-classloader/src/main/java/org/apache/jackrabbit/net/JCRURLConnection.java?rev=697809&r1=697808&r2=697809&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-classloader/src/main/java/org/apache/jackrabbit/net/JCRURLConnection.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-classloader/src/main/java/org/apache/jackrabbit/net/JCRURLConnection.java Mon Sep 22 06:12:57 2008
@@ -48,16 +48,18 @@
* identify and access a repository Property based on the URL. This
* main task is executed in the {@link #connect()} method.
*

- * Basically the guideposts to access content from a JCR Repository URl are
+ * Basically the guideposts to access content from a JCR Repository URL are
* the following:
*

*

The URL must ultimately resolve to a repository property to provide
* content.
*

If the URL itself is the path to a property, that property is used to
* provide the content.
- *

If the URL is a path to a node, the primary item chain starting with
- * this node is followed until no further primary items exist. If the
- * final item is a property, that property is used to provide the content.
+ *

If the URL is a path to a node, either the
+ * jcr:content/jcr:data or jcr:data property is
+ * used or the primary item chain starting with this node is followed until
+ * no further primary items exist. If the final item is a property, that
+ * property is used to provide the content.
*

If neither of the above methods resolve to a property, the
* {@link #connect()} fails and access to the content is not possible.
*

@@ -88,30 +90,25 @@
* representation of the value for all other value types.
*
*

Content-Type
- *

If the property is a child of a nt:resource node, the
- * content type is retrieved from the jcr:mimeType
- * property of the parent node. If the parent node is not a
- * nt:resource, the guessContentTypeFromName
- * method is called on the {@link #getPath() path}. If this does not
- * yield a content type, it is set to application/octet-stream
- * for binary properties and to text/plain for other types.
+ *

The content type is retrieved from the jcr:mimeType
+ * property of the property's parent node if existing. Otherwise the
+ * guessContentTypeFromName method is called on the
+ * {@link #getPath() path}. If this does not yield a content type, it is
+ * set to application/octet-stream for binary properties and
+ * to text/plain for other types.
*
*

Content-Enconding
- *

If the property is a child of a nt:resource node, the
- * content encoding is retrieved from the jcr:econding
- * property of the parent node. If the jcr:encoding property
- * is not set, this header field remains undefined (aka null).
+ *

The content encoding is retrieved from the jcr:econding
+ * property of the property's parent node if existing. Otherwise this
+ * header field remains undefined (aka null).
*
*

Last-Modified
- *

If the property is a child of a nt:resource node, the
- * last modified type is retrieved from the jcr:lastModified
- * property of the parent node. If the parent node is not a
- * nt:resource, the last modification time is set to zero.
+ *

The last modified type is retrieved from the jcr:lastModified
+ * property of the property's parent node if existing. Otherwise the last
+ * modification time is set to zero.
*
*

The content length header field is set from the property length
* (Property.getLength())).
- *

If the property's parent node is of node type nt:resource,
- * the header fields for the content type, content encoding and last
+ *

The header fields for the content type, content encoding and last
* modification time are set from the jcr:mimeType,
* jcr:encoding, and jcr:lastModification
- * properties. Otherwise the content encoding field is set to
- * null and the last modification time is set to zero.
- * The content type field is guessed from the name of the URL item.
- * If the content type cannot be guessed, it is set to
- * application/octet-stream if the property is of binary
- * type or text/plain otherwise.
+ * properties of the property's parent node if existing. Otherwise the
+ * content encoding field is set to null and the last
+ * modification time is set to zero. The content type field is guessed
+ * from the name of the URL item. If the content type cannot be
+ * guessed, it is set to application/octet-stream if the
+ * property is of binary type or text/plain otherwise.
*
*