jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r512695 - in /jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons: AbstractItem.java AbstractNode.java AbstractProperty.java
Date Wed, 28 Feb 2007 10:42:14 GMT
Author: jukka
Date: Wed Feb 28 02:42:13 2007
New Revision: 512695

URL: http://svn.apache.org/viewvc?view=rev&rev=512695
Log:
JCR-742: Added abstract base classes for nodes and properties.

Added:
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractItem.java   (with props)
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractNode.java   (with props)
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractProperty.java   (with props)

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractItem.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractItem.java?view=auto&rev=512695
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractItem.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractItem.java Wed Feb 28 02:42:13 2007
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons;
+
+import javax.jcr.Item;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
+
+/**
+ * Abstract base class for implementing the JCR {@link Item} interface.
+ * <p>
+ * {@link Item} methods <em>without</em> a default implementation:
+ * <ul>
+ *   <li>{@link Item#accept(javax.jcr.ItemVisitor)}</li>
+ *   <li>{@link Item#getName()}</li>
+ *   <li>{@link Item#getParent()}</li>
+ *   <li>{@link Item#getPath()}</li>
+ *   <li>{@link Item#getSession()}</li>
+ *   <li>{@link Item#isModified()}</li>
+ *   <li>{@link Item#isNew()}</li>
+ *   <li>{@link Item#isNode()}</li>
+ *   <li>{@link Item#isSame(Item)}</li>
+ *   <li>{@link Item#refresh(boolean)}</li>
+ *   <li>{@link Item#remove()}</li>
+ *   <li>{@link Item#save()}</li>
+ * </ul>
+ */
+public abstract class AbstractItem implements Item {
+
+    /**
+     * Returns the ancestor of this item at the given depth from the
+     * root node.
+     * <p>
+     * The default implementation returns this item if the given depth
+     * equals the return value of the {@link Item#getDepth()} method.
+     * Otherwise calls the method recursively on the parent node.
+     *
+     * @param depth depth of the returned ancestor item
+     * @return ancestor item
+     * @throws RepositoryException if an error occurs
+     */
+    public Item getAncestor(int depth) throws RepositoryException {
+        if (getDepth() == depth) {
+            return this;
+        } else {
+            return getParent().getAncestor(depth);
+        }
+    }
+
+    /**
+     * Returns the depth of this item.
+     * <p>
+     * Recursively calls the method on the parent node and increments
+     * the return value to get the depth of this item. Returns zero if
+     * the parent node is not available (i.e. this is the root node).
+     *
+     * @return depth of this item
+     * @throws RepositoryException if an error occurs
+     */
+    public int getDepth() throws RepositoryException {
+        try {
+            return getParent().getDepth() + 1;
+        } catch (ItemNotFoundException e) {
+            return 0;
+        }
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractNode.java?view=auto&rev=512695
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractNode.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractNode.java Wed Feb 28 02:42:13 2007
@@ -0,0 +1,770 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons;
+
+import java.io.InputStream;
+import java.util.Calendar;
+
+import javax.jcr.Item;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.ItemVisitor;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+
+import org.apache.jackrabbit.name.QName;
+
+/**
+ * Abstract base class for implementing the JCR {@link Node} interface.
+ * <p>
+ * {@link Item} methods <em>without</em> a default implementation:
+ * <ul>
+ *   <li>{@link Item#accept(javax.jcr.ItemVisitor)}</li>
+ *   <li>{@link Item#getName()}</li>
+ *   <li>{@link Item#getParent()}</li>
+ *   <li>{@link Item#getSession()}</li>
+ *   <li>{@link Item#isModified()}</li>
+ *   <li>{@link Item#isNew()}</li>
+ *   <li>{@link Item#isSame(Item)}</li>
+ *   <li>{@link Item#refresh(boolean)}</li>
+ *   <li>{@link Item#remove()}</li>
+ *   <li>{@link Item#save()}</li>
+ * </ul>
+ * <p>
+ * {@link Node} methods <em>without</em> a default implementation:
+ * <ul>
+ *   <li>{@link Node#addMixin(String)}</li>
+ *   <li>{@link Node#addNode(String)}</li>
+ *   <li>{@link Node#addNode(String, String))}</li>
+ *   <li>{@link Node#canAddMixin(String)}</li>
+ *   <li>{@link Node#cancelMerge(Version)}</li>
+ *   <li>{@link Node#checkin()}</li>
+ *   <li>{@link Node#checkout()}</li>
+ *   <li>{@link Node#doneMerge(Version)}</li>
+ *   <li>{@link Node#getBaseVersion()}</li>
+ *   <li>{@link Node#getCorrespondingNodePath(String)}</li>
+ *   <li>{@link Node#getDefinition()}</li>
+ *   <li>{@link Node#getIndex()}</li>
+ *   <li>{@link Node#getLock()}</li>
+ *   <li>{@link Node#getNode(String)}</li>
+ *   <li>{@link Node#getNodes()}</li>
+ *   <li>{@link Node#getNodes(String)}</li>
+ *   <li>{@link Node#getPrimaryItem()}</li>
+ *   <li>{@link Node#getProperties()}</li>
+ *   <li>{@link Node#getProperties(String)}</li>
+ *   <li>{@link Node#getReferences()}</li>
+ *   <li>{@link Node#lock(boolean, boolean)}</li>
+ *   <li>{@link Node#merge(String, boolean)}</li>
+ *   <li>{@link Node#orderBefore(String, String)}</li>
+ *   <li>{@link Node#removeMixin(String)}</li>
+ *   <li>{@link Node#restore(Version, String, boolean)}</li>
+ *   <li>{@link Node#setProperty(String, Value)}</li>
+ *   <li>{@link Node#setProperty(String, Value[])}</li>
+ *   <li>{@link Node#unlock()}</li>
+ *   <li>{@link Node#update(String)}</li>
+ * </ul>
+ */
+public abstract class AbstractNode extends AbstractItem implements Node {
+
+    //----------------------------------------------------------------< Item >
+
+    /**
+     * Accepts the given item visitor.
+     * <p>
+     * The default implementation calls {@link ItemVisitor#visit(Node)} on
+     * the given visitor with this node as the argument.
+     *
+     * @param visitor item visitor
+     * @throws RepositoryException if an error occurs
+     */
+    public void accept(ItemVisitor visitor) throws RepositoryException {
+        visitor.visit(this);
+    }
+
+    /**
+     * Returns the path of this node.
+     * <p>
+     * The default implementation recursively calls this method on the
+     * parent node and appends the name and optionally the index of this
+     * node to construct the full path. Returns "/" if the parent node is
+     * not available (i.e. this is the root node).
+     *
+     * @return node path
+     * @throws RepositoryException if an error occurs
+     */
+    public String getPath() throws RepositoryException {
+        try {
+            StringBuffer buffer = new StringBuffer(getParent().getPath());
+            if (buffer.length() > 1) {
+                buffer.append('/');
+            }
+            buffer.append(getName());
+            int index = getIndex();
+            if (index != 1) {
+                buffer.append('[');
+                buffer.append(index);
+                buffer.append(']');
+            }
+            return buffer.toString();
+        } catch (ItemNotFoundException e) {
+            return "/";
+        }
+    }
+
+    /**
+     * Returns <code>true</code>.
+     *
+     * @return <code>true</code>
+     */
+    public boolean isNode() {
+        return true;
+    }
+
+    //----------------------------------------------------------------< Node >
+
+    /**
+     * Returns the declared mixin node types of this node.
+     * <p>
+     * The default implementation uses the values of the
+     * <code>jcr:mixinTypes</code> property to look up the mixin node types
+     * from the {@link NodeTypeManager} of the current workspace.
+     *
+     * @return mixin node types
+     * @throws RepositoryException if an error occurs
+     */
+    public NodeType[] getMixinNodeTypes() throws RepositoryException {
+        try {
+            NodeTypeManager manager =
+                getSession().getWorkspace().getNodeTypeManager();
+            Property property = getProperty(getName(QName.JCR_MIXINTYPES));
+            Value[] values = property.getValues();
+            NodeType[] types = new NodeType[values.length];
+            for (int i = 0; i < values.length; i++) {
+                types[i] = manager.getNodeType(values[i].getString());
+            }
+            return types;
+        } catch (PathNotFoundException e) {
+            // jcr:mixinTypes does not exist, i.e. no mixin types on this node
+            return new NodeType[0];
+        }
+    }
+
+    /**
+     * Returns the primary node type of this node.
+     * <p>
+     * The default implementation uses the value of the
+     * <code>jcr:primaryType</code> property to look up the primary
+     * node type from the {@link NodeTypeManager} of the current workspace.
+     *
+     * @return primary node type
+     * @throws RepositoryException if an error occurs
+     */
+    public NodeType getPrimaryNodeType() throws RepositoryException {
+        NodeTypeManager manager =
+            getSession().getWorkspace().getNodeTypeManager();
+        Property property = getProperty(getName(QName.JCR_PRIMARYTYPE));
+        return manager.getNodeType(property.getString());
+    }
+
+    /**
+     * Returns the property at the given relative path from this node.
+     * <p>
+     * The default implementation looks up the parent node of the given
+     * relative path and iterates through the properties of that node to
+     * find and return the identified property.
+     *
+     * @param relPath relative path of the property
+     * @return property
+     * @throws PathNotFoundException if the property is not found
+     * @throws RepositoryException if an error occurs
+     */
+    public Property getProperty(String relPath)
+            throws PathNotFoundException, RepositoryException {
+        // Corner case, remove any "/." self references at the end of the path
+        while (relPath.endsWith("/.")) {
+            relPath = relPath.substring(0, relPath.length() - 2);
+        }
+
+        // Find the parent node of the identified property
+        Node node = this;
+        int slash = relPath.lastIndexOf('/');
+        if (slash == 0) {
+            node = getSession().getRootNode();
+            relPath = relPath.substring(1);
+        } else if (slash > 0) {
+            node = getNode(relPath.substring(0, slash));
+            relPath = relPath.substring(slash + 1);
+        }
+
+        // Look for the named property. Must iterate and re-check for the name
+        // since the client could have used an invalid path like "./a|b".
+        PropertyIterator properties = node.getProperties(relPath);
+        while (properties.hasNext()) {
+            Property property = (Property) properties.next();
+            if (relPath.equals(property.getName())) {
+                return property;
+            }
+        }
+
+        throw new PathNotFoundException("Property not found: " + relPath);
+    }
+
+    /**
+     * Returns the UUID of this node.
+     * <p>
+     * The default implementation checks if this node is referenceable (i.e. of
+     * type <code>mix:referenceable</code>) and returns the contents of the
+     * <code>jcr:uuid</code> property if it is.
+     *
+     * @return node UUID
+     * @throws UnsupportedRepositoryOperationException
+     *         if this node is not referenceable
+     * @throws RepositoryException if an error occurs
+     */
+    public String getUUID()
+            throws UnsupportedRepositoryOperationException, RepositoryException {
+        if (isNodeType(getName(QName.MIX_REFERENCEABLE))) {
+            return getProperty(getName(QName.JCR_UUID)).getString();
+        } else {
+            throw new UnsupportedRepositoryOperationException(
+                    "This node is not referenceable: " + getPath());
+        }
+    }
+
+    /**
+     * Returns the version history of this node.
+     * <p>
+     * The default implementation returns the containing version history of
+     * the base version of this node.
+     *
+     * @return version history
+     * @throws RepositoryException if an error occurs
+     */
+    public VersionHistory getVersionHistory() throws RepositoryException {
+        return getBaseVersion().getContainingHistory();
+    }
+
+    /**
+     * Checks whether a node at the given relative path exists.
+     * <p>
+     * The default implementation looks up the node using
+     * {@link Node#getNode(String)} and returns <code>true</code> if
+     * a {@link PathNotFoundException} is not thrown.
+     *
+     * @param relPath relative path
+     * @return <code>true</code> if a node exists at the given path,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean hasNode(String relPath) throws RepositoryException {
+        try {
+            getNode(relPath);
+            return true;
+        } catch (PathNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks if this node has one or more properties.
+     * <p>
+     * The default implementation calls {@link Node#getNodes()} and returns
+     * <code>true</code> iff returned iterator has at least one element.
+     *
+     * @return <code>true</code> if this node has child nodes,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean hasNodes() throws RepositoryException {
+        return getNodes().hasNext();
+    }
+
+    /**
+     * Checks if this node has one or more properties.
+     * <p>
+     * The default implementation calls {@link Node#getProperties()} and
+     * returns <code>true</code> iff returned iterator has at least one element.
+     * <p>
+     * Note that in normal circumstances (i.e. no weird access controls) this
+     * method will always return <code>true</code> since all nodes always have
+     * at least the <code>jcr:primaryType</code> property.
+     *
+     * @return <code>true</code> if this node has properties,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean hasProperties() throws RepositoryException {
+        return getProperties().hasNext();
+    }
+
+    /**
+     * Checks whether a property at the given relative path exists.
+     * <p>
+     * The default implementation looks up the property using
+     * {@link Node#getProperty(String)} and returns <code>true</code> if
+     * a {@link PathNotFoundException} is not thrown.
+     *
+     * @param relPath relative path
+     * @return <code>true</code> if a property exists at the given path,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean hasProperty(String relPath) throws RepositoryException {
+        try {
+            getProperty(relPath);
+            return true;
+        } catch (PathNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks if this node holds a lock.
+     * <p>
+     * The default implementation calls {@link Node#getLock()} and returns
+     * <code>true</code> iff the holding node of the lock is the same as this
+     * node.
+     *
+     * @return <code>true</code> if this node holds a lock,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean holdsLock() throws RepositoryException {
+        try {
+            return isSame(getLock().getNode());
+        } catch (LockException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether this node is checked out.
+     * <p>
+     * The default implementation checks the <code>jcr:isCheckedOut</code>
+     * property if this node is versionable, and recursively calls this method
+     * on the parent node if this node is not versionable. A non-versionable
+     * root node always returns <code>true</code> from this method.
+     *
+     * @return <code>true</code> if this node is checked out,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean isCheckedOut() throws RepositoryException {
+        if (isNodeType(getName(QName.MIX_VERSIONABLE))) {
+            // This node is versionable, check the jcr:isCheckedOut property
+            return getProperty(getName(QName.JCR_ISCHECKEDOUT)).getBoolean();
+        } else {
+            try {
+                // This node is not versionable, is the parent checked out?
+                return getParent().isCheckedOut();
+            } catch (ItemNotFoundException e) {
+                // This node is the root node, always checked out
+                return true;
+            }
+        }
+    }
+
+    /**
+     * Checks if this node is locked.
+     * <p>
+     * The default implementation calls {@link Node#getLock()} and returns
+     * <code>true</code> iff a {@link LockException} is not thrown.
+     *
+     * @return <code>true</code> if this node is locked,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean isLocked() throws RepositoryException {
+        try {
+            getLock();
+            return true;
+        } catch (LockException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether this node is of the given type.
+     * <p>
+     * The default implementation iterates through the primary and mixin
+     * types and all the supertypes of this node, returning <code>true</code>
+     * if a type with the given name is encountered. Returns <code>false</code>
+     * if none of the types matches.
+     *
+     * @param name type name
+     * @return <code>true</code> if this node is of the given type,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean isNodeType(String name) throws RepositoryException {
+        NodeType type = getPrimaryNodeType();
+        if (name.equals(type.getName())) {
+            return true;
+        }
+        NodeType[] supertypes = type.getSupertypes();
+        for (int i = 0; i < supertypes.length; i++) {
+            if (name.equals(supertypes[i].getName())) {
+                return true;
+            }
+        }
+
+        NodeType[] mixins = getMixinNodeTypes();
+        for (int i = 0; i < mixins.length; i++) {
+            if (name.equals(mixins[i].getName())) {
+                return true;
+            }
+            supertypes = mixins[i].getSupertypes();
+            for (int j = 0; j < supertypes.length; j++) {
+                if (name.equals(supertypes[j].getName())) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Restores this node to the version with the given name.
+     * <p>
+     * The default implement retrieves the named {@link Version} from the
+     * associated {@link VersionHistory} and forwards the call to the
+     * {@link Node#restore(Version, boolean)} method.
+     *
+     * @param versionName version name
+     * @param removeExisting passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void restore(String versionName, boolean removeExisting)
+            throws RepositoryException {
+        restore(getVersionHistory().getVersion(versionName), removeExisting);
+    }
+
+    /**
+     * Restores this node to the given version.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#restore(Version, String, boolean)} method using the
+     * relative path ".".
+     *
+     * @param version passed through
+     * @param removeExisting passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void restore(Version version, boolean removeExisting)
+            throws RepositoryException {
+        restore(version, ".", removeExisting);
+    }
+
+    /**
+     * Restores this node to the version with the given label.
+     * <p>
+     * The default implement retrieves the labeled {@link Version} from the
+     * associated {@link VersionHistory} and forwards the call to the
+     * {@link Node#restore(Version, boolean)} method.
+     *
+     * @param versionLabel version label
+     * @param removeExisting passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void restoreByLabel(String versionLabel, boolean removeExisting)
+            throws RepositoryException {
+        restore(getVersionHistory().getVersionByLabel(versionLabel),
+                removeExisting);
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instances from
+     * the given string values and forwards the call to the
+     * {@link Node#setProperty(String, Value[])} method.
+     *
+     * @param name property name
+     * @param strings string values
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, String[] strings)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        Value[] values = new Value[strings.length];
+        for (int i = 0; i < strings.length; i++) {
+            values[i] = factory.createValue(strings[i]);
+        }
+        return setProperty(name, values);
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instance from
+     * the given string value and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value string value
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, String value)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        return setProperty(name, factory.createValue(value));
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instance from
+     * the given binary value and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value binary value
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, InputStream value)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        return setProperty(name, factory.createValue(value));
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instance from
+     * the given boolean value and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value boolean value
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, boolean value)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        return setProperty(name, factory.createValue(value));
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instance from
+     * the given double value and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value double value
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, double value)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        return setProperty(name, factory.createValue(value));
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instance from
+     * the given long value and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value long value
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, long value)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        return setProperty(name, factory.createValue(value));
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instance from
+     * the given date value and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value date value
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, Calendar value)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        return setProperty(name, factory.createValue(value));
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instance from
+     * the given reference value and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value reference value
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, Node value)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        return setProperty(name, factory.createValue(value));
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to convert the given value to the given
+     * type and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value property value
+     * @param type property type
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, Value value, int type)
+            throws RepositoryException {
+        if (value.getType() != type) {
+            ValueFactory factory = getSession().getValueFactory();
+            value = factory.createValue(value.getString(), type);
+        }
+        return setProperty(name, value);
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to convert the given values to the given
+     * type and forwards the call to the
+     * {@link Node#setProperty(String, Value[])} method.
+     *
+     * @param name property name
+     * @param values property values
+     * @param type property type
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, Value[] values, int type)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        Value[] converted = new Value[values.length];
+        for (int i = 0; i < values.length; i++) {
+            if (values[i].getType() != type) {
+                converted[i] = factory.createValue(values[i].getString(), type);
+            } else {
+                converted[i] = values[i];
+            }
+        }
+        return setProperty(name, converted);
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create {@link Value} instances of the
+     * given type from the given string values and forwards the call to the
+     * {@link Node#setProperty(String, Value[])} method.
+     *
+     * @param name property name
+     * @param strings string values
+     * @param type property type
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, String[] strings, int type)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        Value[] values = new Value[strings.length];
+        for (int i = 0; i < strings.length; i++) {
+            values[i] =  factory.createValue(strings[i], type);
+        }
+        return setProperty(name, values);
+    }
+
+    /**
+     * Sets the value of the named property.
+     * <p>
+     * The default implementation uses the {@link ValueFactory} of the
+     * current {@link Session} to create a {@link Value} instance of the
+     * given type from the given string value and forwards the call to the
+     * {@link Node#setProperty(String, Value)} method.
+     *
+     * @param name property name
+     * @param value string value
+     * @param type property type
+     * @return modified property
+     * @throws RepositoryException if an error occurs
+     */
+    public Property setProperty(String name, String value, int type)
+            throws RepositoryException {
+        ValueFactory factory = getSession().getValueFactory();
+        return setProperty(name, factory.createValue(value, type));
+    }
+
+    //-------------------------------------------------------------< private >
+
+    /**
+     * Returns the prefixed JCR name for the given {@link QName} using the
+     * current namespace mappings. The given name is assumed <em>not</em>
+     * to be in the default namespace, i.e. there will always be a non-empty
+     * prefix for the name.
+     *
+     * @param name namespaced name
+     * @return prefixed JCR name
+     * @throws RepositoryException if an error occurs
+     */
+    private String getName(QName name) throws RepositoryException {
+        assert name.getNamespaceURI().length() > 0;
+        String prefix = getSession().getNamespacePrefix(name.getNamespaceURI());
+        return prefix + ":" + name.getLocalName();
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractNode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractProperty.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractProperty.java?view=auto&rev=512695
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractProperty.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractProperty.java Wed Feb 28 02:42:13 2007
@@ -0,0 +1,426 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+
+import javax.jcr.Item;
+import javax.jcr.ItemVisitor;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+
+/**
+ * Abstract base class for implementing the JCR {@link Property} interface.
+ * <p>
+ * {@link Item} methods <em>without</em> a default implementation:
+ * <ul>
+ *   <li>{@link Item#getName()}</li>
+ *   <li>{@link Item#getParent()}</li>
+ *   <li>{@link Item#getSession()}</li>
+ *   <li>{@link Item#isModified()}</li>
+ *   <li>{@link Item#isNew()}</li>
+ *   <li>{@link Item#isSame(Item)}</li>
+ *   <li>{@link Item#refresh(boolean)}</li>
+ *   <li>{@link Item#remove()}</li>
+ *   <li>{@link Item#save()}</li>
+ * </ul>
+ * <p>
+ * {@link Property} methods <em>without</em> a default implementation:
+ * <ul>
+ *   <li>{@link Property#getDefinition()}</li>
+ *   <li>{@link Property#getValue()}</li>
+ *   <li>{@link Property#getValues()}</li>
+ * </ul>
+ */
+public abstract class AbstractProperty extends AbstractItem
+        implements Property {
+
+    //----------------------------------------------------------------< Item >
+
+    /**
+     * Accepts the given item visitor.
+     * <p>
+     * The default implementation calls {@link ItemVisitor#visit(Property)}
+     * on the given visitor with this property as the argument.
+     *
+     * @param visitor item visitor
+     * @throws RepositoryException if an error occurs
+     */
+    public void accept(ItemVisitor visitor) throws RepositoryException {
+        visitor.visit(this);
+    }
+
+    /**
+     * Returns the path of this property.
+     * <p>
+     * The default implementation constructs the path from the path of the
+     * parent node and the name of this property.
+     *
+     * @return property path
+     * @throws RepositoryException if an error occurs
+     */
+    public String getPath() throws RepositoryException {
+        StringBuffer buffer = new StringBuffer(getParent().getPath());
+        if (buffer.length() > 1) {
+            buffer.append('/');
+        }
+        buffer.append(getName());
+        return buffer.toString();
+    }
+
+    /**
+     * Returns <code>false</code>.
+     *
+     * @return <code>false</code>
+     */
+    public boolean isNode() {
+        return false;
+    }
+
+    //------------------------------------------------------------< Property >
+
+    /**
+     * Returns the boolean value of this property.
+     * <p>
+     * The default implementation forwards the method call to the
+     * {@link Value} instance returned by the generic
+     * {@link Property#getValue()} method.
+     *
+     * @return boolean value
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean getBoolean() throws RepositoryException {
+        return getValue().getBoolean();
+    }
+
+    /**
+     * Returns the date value of this property.
+     * <p>
+     * The default implementation forwards the method call to the
+     * {@link Value} instance returned by the generic
+     * {@link Property#getValue()} method.
+     *
+     * @return date value
+     * @throws RepositoryException if an error occurs
+     */
+    public Calendar getDate() throws RepositoryException {
+        return getValue().getDate();
+    }
+
+    /**
+     * Returns the double value of this property.
+     * <p>
+     * The default implementation forwards the method call to the
+     * {@link Value} instance returned by the generic
+     * {@link Property#getValue()} method.
+     *
+     * @return double value
+     * @throws RepositoryException if an error occurs
+     */
+    public double getDouble() throws RepositoryException {
+        return getValue().getDouble();
+    }
+
+    /**
+     * Returns the length of the value of this property.
+     * <p>
+     * The default implementation measures the length of the {@link Value}
+     * instance returned by the generic {@link Property#getValue()} method.
+     *
+     * @return length of the property value
+     * @throws RepositoryException if an error occurs
+     */
+    public long getLength() throws RepositoryException {
+        return getLength(getValue());
+    }
+
+    /**
+     * Returns the lengths of the values of this property.
+     * <p>
+     * The default implementation measures the lengths of the {@link Value}
+     * instances returned by the generic {@link Property#getValues()} method.
+     *
+     * @return lengths of the property values
+     * @throws RepositoryException if an error occurs
+     */
+    public long[] getLengths() throws RepositoryException {
+        Value[] values = getValues();
+        long[] lengths = new long[values.length];
+        for (int i = 0; i < values.length; i++) {
+            lengths[i] = getLength(values[i]);
+        }
+        return lengths;
+    }
+
+    /**
+     * Returns the long value of this property.
+     * <p>
+     * The default implementation forwards the method call to the
+     * {@link Value} instance returned by the generic
+     * {@link Property#getValue()} method.
+     *
+     * @return long value
+     * @throws RepositoryException if an error occurs
+     */
+    public long getLong() throws RepositoryException {
+        return getValue().getLong();
+    }
+
+    /**
+     * Returns the node referenced by this property.
+     * <p>
+     * The default implementation checks that this property is a reference
+     * property (or tries to convert the property value to a reference) and
+     * uses {@link Session#getNodeByUUID(String)} to retrieve the
+     * referenced node.
+     *
+     * @return node referenced by this property
+     * @throws RepositoryException if an error occurs
+     */
+    public Node getNode() throws RepositoryException {
+        Session session = getSession();
+        String uuid = getString();
+        if (getType() != PropertyType.REFERENCE) {
+            uuid = session.getValueFactory().createValue(
+                    uuid, PropertyType.REFERENCE).getString();
+        }
+        return session.getNodeByUUID(uuid);
+    }
+
+    /**
+     * Returns the binary value of this property.
+     * <p>
+     * The default implementation forwards the method call to the
+     * {@link Value} instance returned by the generic
+     * {@link Property#getValue()} method.
+     *
+     * @return binary value
+     * @throws RepositoryException if an error occurs
+     */
+    public InputStream getStream() throws RepositoryException {
+        return getValue().getStream();
+    }
+
+    /**
+     * Returns the string value of this property.
+     * <p>
+     * The default implementation forwards the method call to the
+     * {@link Value} instance returned by the generic
+     * {@link Property#getValue()} method.
+     *
+     * @return string value
+     * @throws RepositoryException if an error occurs
+     */
+    public String getString() throws RepositoryException {
+        return getValue().getString();
+    }
+
+    /**
+     * Returns the type of this property.
+     * <p>
+     * The default implementation forwards the method call to the
+     * {@link Value} instance returned by the generic
+     * {@link Property#getValue()} method.
+     *
+     * @return property type
+     * @throws RepositoryException if an error occurs
+     */
+    public int getType() throws RepositoryException {
+        return getValue().getType();
+    }
+
+    /**
+     * Sets the value of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, Value)} method of the parent node
+     * using the name of this property.
+     *
+     * @param value passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(Value value) throws RepositoryException {
+        getParent().setProperty(getName(), value);
+    }
+
+    /**
+     * Sets the values of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, Value[])} method of the parent node
+     * using the name of this property.
+     *
+     * @param values passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(Value[] values) throws RepositoryException {
+        getParent().setProperty(getName(), values);
+    }
+
+    /**
+     * Sets the value of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, String)} method of the parent node
+     * using the name of this property.
+     *
+     * @param value passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(String value) throws RepositoryException {
+        getParent().setProperty(getName(), value);
+    }
+
+    /**
+     * Sets the values of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, String[])} method of the parent node
+     * using the name of this property.
+     *
+     * @param values passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(String[] values) throws RepositoryException {
+        getParent().setProperty(getName(), values);
+    }
+
+    /**
+     * Sets the value of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, InputStream)} method of the parent node
+     * using the name of this property.
+     *
+     * @param value passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(InputStream value) throws RepositoryException {
+        getParent().setProperty(getName(), value);
+    }
+
+    /**
+     * Sets the value of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, long)} method of the parent node
+     * using the name of this property.
+     *
+     * @param value passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(long value) throws RepositoryException {
+        getParent().setProperty(getName(), value);
+    }
+
+    /**
+     * Sets the value of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, double)} method of the parent node
+     * using the name of this property.
+     *
+     * @param value passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(double value) throws RepositoryException {
+        getParent().setProperty(getName(), value);
+    }
+
+    /**
+     * Sets the value of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, Calendar)} method of the parent node
+     * using the name of this property.
+     *
+     * @param value passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(Calendar value) throws RepositoryException {
+        getParent().setProperty(getName(), value);
+    }
+
+    /**
+     * Sets the value of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, boolean)} method of the parent node
+     * using the name of this property.
+     *
+     * @param value passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(boolean value) throws RepositoryException {
+        getParent().setProperty(getName(), value);
+    }
+
+    /**
+     * Sets the value of this property.
+     * <p>
+     * The default implementation forwards the call to the
+     * {@link Node#setProperty(String, Node)} method of the parent node
+     * using the name of this property.
+     *
+     * @param value passed through
+     * @throws RepositoryException if an error occurs
+     */
+    public void setValue(Node value) throws RepositoryException {
+        getParent().setProperty(getName(), value);
+    }
+
+    //-------------------------------------------------------------< private >
+
+    /**
+     * Returns the length of the given value.
+     *
+     * @param value value
+     * @return length of the value
+     * @throws RepositoryException if an error occurs
+     */
+    private long getLength(Value value) throws RepositoryException {
+        if (value.getType() != PropertyType.BINARY) {
+            return value.getString().length();
+        } else {
+            try {
+                InputStream stream = value.getStream();
+                try {
+                    long length = 0;
+                    byte[] buffer = new byte[4096];
+                    int n = stream.read(buffer);
+                    while (n != -1) {
+                        length += n;
+                        n = stream.read(buffer);
+                    }
+                    return length;
+                } finally {
+                    stream.close();
+                }
+            } catch (IOException e) {
+                throw new RepositoryException(
+                        "Failed to count the length of a binary value", e);
+            }
+        }
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message