Index: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitSession.java =================================================================== --- jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitSession.java (Revision 1455474) +++ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitSession.java (Arbeitskopie) @@ -16,14 +16,16 @@ */ package org.apache.jackrabbit.api; -import org.apache.jackrabbit.api.security.user.UserManager; -import org.apache.jackrabbit.api.security.principal.PrincipalManager; - -import javax.jcr.Session; import javax.jcr.AccessDeniedException; +import javax.jcr.ItemNotFoundException; import javax.jcr.RepositoryException; +import javax.jcr.Session; import javax.jcr.UnsupportedRepositoryOperationException; +import javax.jcr.Value; +import org.apache.jackrabbit.api.security.principal.PrincipalManager; +import org.apache.jackrabbit.api.security.user.UserManager; + /** * JackrabbitSession... */ @@ -55,4 +57,32 @@ */ UserManager getUserManager() throws AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException; -} \ Kein Zeilenumbruch am Ende der Datei + /** + * Returns the {@code Value} identified by the given content identity. This + * content identity is expected to be an opaque string value returned by a + * previous call to the {@link JackrabbitValue#getContentIdentity()} method. + *

+ * The implementation must make sure that round tripping between this + * method and the {@link JackrabbitValue#getContentIdentity()} method exists, such that + * the following assertions hold: + *

+     *   JackrabbitSession s = ...;
+     *   JackrabbitValue jv0 = ...;
+     *   String id = jv0.getContentIdentity();
+     *   assert(id != null);
+     *   Value v1 = s.getValueByContentIdentity(id);
+     *   assert(v1 instanceof JackrabbitValue);
+     *   assert(id.equals(((JackrabbitValue) v1).getContentIdentity()));
+     * 
+ * + * @param contentIdentity The identitiy of the value to return. + * @return The {@link Value} identified by the content identity. + * @throws ItemNotFoundException If no value with the given + * {@code contentIdentity} exists. + * @throws RepositoryException If another error occurrs. + * @throws NullPointerException if {@code ContentIdentity} is {@code null}. + * @see JackrabbitValue#getContentIdentity() + */ + Value getValueByContentIdentity(String contentIdentity) throws ItemNotFoundException, RepositoryException; + +} Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (Revision 1455474) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (Arbeitskopie) @@ -49,6 +49,7 @@ import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.jcr.UnsupportedRepositoryOperationException; +import javax.jcr.Value; import javax.jcr.ValueFactory; import javax.jcr.Workspace; import javax.jcr.lock.Lock; @@ -70,6 +71,8 @@ import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.jackrabbit.commons.AbstractSession; import org.apache.jackrabbit.core.config.WorkspaceConfig; +import org.apache.jackrabbit.core.data.DataIdentifier; +import org.apache.jackrabbit.core.data.DataStoreException; import org.apache.jackrabbit.core.data.GarbageCollector; import org.apache.jackrabbit.core.id.NodeId; import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; @@ -89,6 +92,7 @@ import org.apache.jackrabbit.core.session.SessionRefreshOperation; import org.apache.jackrabbit.core.session.SessionSaveOperation; import org.apache.jackrabbit.core.state.SessionItemStateManager; +import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.core.version.InternalVersionManager; import org.apache.jackrabbit.core.xml.ImportHandler; import org.apache.jackrabbit.core.xml.SessionImporter; @@ -103,6 +107,7 @@ import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; import org.apache.jackrabbit.spi.commons.name.NameConstants; import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver; +import org.apache.jackrabbit.spi.commons.value.ValueFormat; import org.apache.jackrabbit.util.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -1121,6 +1126,29 @@ } /** + * @see JackrabbitSession#getValueByContentIdentity(String) + * @since TODO + */ + @Override + public Value getValueByContentIdentity(String contentIdentity) throws ItemNotFoundException, RepositoryException { + try { + context.getAccessManager().checkRepositoryPermission(Permission.READ_VALUE_BY_CONTENT_IDENTITY); + InternalValue iv = InternalValue.getInternalValue(new DataIdentifier(contentIdentity), + repositoryContext.getDataStore(), true); + if (iv != null) { + return ValueFormat.getJCRValue(iv, context, getValueFactory()); + } + } catch (AccessDeniedException ade) { + // fall through to default behaviour (not found) + } catch (DataStoreException dse) { + throw new RepositoryException(contentIdentity, dse); + } + + // fall back to no value found + throw new ItemNotFoundException(contentIdentity); + } + + /** * @see javax.jcr.Session#nodeExists(String) * @since JCR 2.0 */ Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java (Revision 1455474) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java (Arbeitskopie) @@ -57,11 +57,13 @@ public static final int PRIVILEGE_MNGMT = WORKSPACE_MNGMT << 1; + public static final int READ_VALUE_BY_CONTENT_IDENTITY = PRIVILEGE_MNGMT << 1; + public static final int ALL = (READ | SET_PROPERTY | ADD_NODE | REMOVE_NODE | REMOVE_PROPERTY | READ_AC | MODIFY_AC | NODE_TYPE_MNGMT | VERSION_MNGMT | LOCK_MNGMT | LIFECYCLE_MNGMT | RETENTION_MNGMT | MODIFY_CHILD_NODE_COLLECTION | NODE_TYPE_DEF_MNGMT | NAMESPACE_MNGMT - | WORKSPACE_MNGMT | PRIVILEGE_MNGMT); + | WORKSPACE_MNGMT | PRIVILEGE_MNGMT | READ_VALUE_BY_CONTENT_IDENTITY); /** * Returns those bits from permissions that are not present in Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java (Revision 1455474) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java (Arbeitskopie) @@ -268,7 +268,7 @@ * @param verify verify if the record exists, and return null if not * @return the internal value or null */ - static InternalValue getInternalValue(DataIdentifier identifier, DataStore store, boolean verify) throws DataStoreException { + public static InternalValue getInternalValue(DataIdentifier identifier, DataStore store, boolean verify) throws DataStoreException { if (verify) { if (store.getRecordIfStored(identifier) == null) { return null; Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ContentIdentityTest.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ContentIdentityTest.java (Revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ContentIdentityTest.java (Arbeitskopie) @@ -0,0 +1,78 @@ +/* + * 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.core; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Arrays; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; +import javax.jcr.Value; +import org.apache.jackrabbit.api.JackrabbitSession; +import org.apache.jackrabbit.api.JackrabbitValue; +import org.apache.jackrabbit.test.AbstractJCRTest; + +/** + * JackrabbitNodeTest... + */ +public class ContentIdentityTest extends AbstractJCRTest { + + private byte[] data; + + private String nodeName; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + // create some content + data = new byte[64 * 1024]; // 64KB of data + Arrays.fill(data, (byte) 99); + + nodeName = getClass().getSimpleName() + "." + System.currentTimeMillis(); + Node node = superuser.getRootNode().addNode(nodeName, "nt:unstructured"); + node.setProperty("jcr:data", new ByteArrayInputStream(data)); + + superuser.save(); + } + + public void test_contentIdentity() throws RepositoryException, IOException { + final Property p = superuser.getProperty("/" + nodeName + "/jcr:data"); + final Value v = p.getValue(); + + assertTrue("Expect Session to be a JackrabbitSession", superuser instanceof JackrabbitSession); + assertTrue("Expect Value to be a JackrabbitValue", v instanceof JackrabbitValue); + + final String ci = ((JackrabbitValue) v).getContentIdentity(); + assertNotNull("Expect content identity to not be null", ci); + + final Value byCi = ((JackrabbitSession) superuser).getValueByContentIdentity(ci); + final Binary bbyCi = byCi.getBinary(); + try { + assertEquals("Expect equal sizes", data.length, bbyCi.getSize()); + byte[] buf = new byte[(int) bbyCi.getSize()]; + assertEquals("Expect all bytes to be read", bbyCi.getSize(), bbyCi.read(buf, 0)); + assertTrue("Expect binary data to be the same", Arrays.equals(data, buf)); + } finally { + bbyCi.dispose(); + } + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PermissionTest.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PermissionTest.java (Revision 1455474) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PermissionTest.java (Arbeitskopie) @@ -44,10 +44,11 @@ assertEquals(512, Permission.LOCK_MNGMT); assertEquals(1024, Permission.LIFECYCLE_MNGMT); assertEquals(2048, Permission.RETENTION_MNGMT); - assertEquals(4096, Permission.MODIFY_CHILD_NODE_COLLECTION); - assertEquals(8192, Permission.NODE_TYPE_DEF_MNGMT); + assertEquals(4096, Permission.MODIFY_CHILD_NODE_COLLECTION); + assertEquals(8192, Permission.NODE_TYPE_DEF_MNGMT); assertEquals(16384, Permission.NAMESPACE_MNGMT); assertEquals(32768, Permission.WORKSPACE_MNGMT); assertEquals(65536, Permission.PRIVILEGE_MNGMT); + assertEquals(131072, Permission.READ_VALUE_BY_CONTENT_IDENTITY); } } \ Kein Zeilenumbruch am Ende der Datei