You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2021/04/15 14:56:32 UTC

[jackrabbit-filevault] branch feature/improve-docviewproperty updated (0c18908 -> 0071538)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a change to branch feature/improve-docviewproperty
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git.


 discard 0c18908  JCRVLT-516 simplify usage of DocViewProperties outside JCR context
     new 0071538  JCRVLT-516 simplify usage of DocViewProperties outside JCR context

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (0c18908)
            \
             N -- N -- N   refs/heads/feature/improve-docviewproperty (0071538)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../jackrabbit/vault/util/DocViewProperty.java      | 21 ++++++++++++++++++++-
 .../apache/jackrabbit/vault/util/package-info.java  |  2 +-
 2 files changed, 21 insertions(+), 2 deletions(-)

[jackrabbit-filevault] 01/01: JCRVLT-516 simplify usage of DocViewProperties outside JCR context

Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch feature/improve-docviewproperty
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git

commit 0071538a2a5cafdd6a4eb916a011699f5ef1f10b
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Thu Apr 15 16:37:38 2021 +0200

    JCRVLT-516 simplify usage of DocViewProperties outside JCR context
    
    provide factory methods taking either Property or Value[]
    allow to format a given DocViewProperty
---
 .../jackrabbit/vault/util/DocViewProperty.java     | 193 +++++++++++++++------
 .../apache/jackrabbit/vault/util/package-info.java |   2 +-
 .../jackrabbit/vault/util/DocViewPropertyTest.java |   8 +-
 3 files changed, 142 insertions(+), 61 deletions(-)

diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewProperty.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewProperty.java
index eb3162f..6ecc286 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewProperty.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewProperty.java
@@ -17,6 +17,7 @@
 
 package org.apache.jackrabbit.vault.util;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -33,16 +34,22 @@ import javax.jcr.ValueFormatException;
 
 import org.apache.jackrabbit.api.ReferenceBinary;
 import org.apache.jackrabbit.commons.jackrabbit.SimpleReferenceBinary;
+import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.util.XMLChar;
 import org.apache.jackrabbit.value.ValueHelper;
-import org.apache.jackrabbit.util.Text;
 
 /**
  * Helper class that represents a (jcr) property in the document view format.
  * It contains formatting and parsing methods for writing/reading enhanced
  * docview properties.
- *
- * {@code prop:= [ "{" type "}" ] ( value | "[" [ value { "," value } ] "]" )}
+ * </p>
+ * The string representation adheres to the following grammar:
+ * <pre>
+ * <code>prop:= [ "{" type "}" ] ( value | "[" [ value { "," value } ] "]" )
+ * {@code type} := {@link PropertyType#nameFromValue(int)} | {@link BINARY_REF}
+ * </code>
+ * </pre>
+ * 
  */
 public class DocViewProperty {
 
@@ -75,9 +82,9 @@ public class DocViewProperty {
     public final boolean isReferenceProperty;
 
     /**
-     * set of unambigous property names
+     * set of unambigous property names (which never need an explicit type descriptor as the types are defined by the spec)
      */
-    private static final Set<String> UNAMBIGOUS = new HashSet<String>();
+    private static final Set<String> UNAMBIGOUS = new HashSet<>();
     static {
         UNAMBIGOUS.add("jcr:primaryType");
         UNAMBIGOUS.add("jcr:mixinTypes");
@@ -95,6 +102,64 @@ public class DocViewProperty {
         this(name, values, multi, type, false);
     }
 
+    public static DocViewProperty fromValues(String name, Value[] values, boolean isMulti, boolean sort, boolean useBinaryReferences) throws RepositoryException {
+        List<String> strValues = new ArrayList<>();
+        if (isMulti) {
+            if (sort) {
+                Arrays.sort(values, ValueComparator.getInstance());
+            }
+        }
+        for (Value value : values) {
+             strValues.add(serializeValue(value, useBinaryReferences));
+        }
+         
+        int type = values[0].getType();
+        boolean isBinaryRef = false;
+        if (type == PropertyType.BINARY && !strValues.get(0).isEmpty()) {
+            isBinaryRef = true;
+        }
+        return new DocViewProperty(name, strValues.toArray(new String[0]), isMulti, type, isBinaryRef);
+    }
+
+    /**
+     * Creates a new property based on a JCR property object
+     * @param prop the jcr property
+     * @param sort if {@code true} multivalue properties should be sorted
+     * @param useBinaryReferences {@code true} to use binary references
+     * @throws RepositoryException 
+     * @throws IllegalArgumentException if single value property and not exactly 1 value is given.
+     */
+    public static DocViewProperty fromProperty(Property prop, boolean sort, boolean useBinaryReferences) throws RepositoryException {
+        boolean isMultiValue = prop.getDefinition().isMultiple();
+        final Value[] values;
+        if (isMultiValue) {
+            values = prop.getValues();
+        } else {
+            values = new Value[] { prop.getValue() };
+        }
+        return fromValues(prop.getName(), values, isMultiValue, sort, useBinaryReferences);
+    }
+
+    static String serializeValue(Value value, boolean useBinaryReferences) throws RepositoryException {
+        // special handling for binaries
+        String strValue = null;
+        if (value.getType() == PropertyType.BINARY) {
+            if (useBinaryReferences) {
+                Binary bin = value.getBinary();
+                if (bin instanceof ReferenceBinary) {
+                    strValue = ((ReferenceBinary) bin).getReference();
+                }
+            }
+            if (strValue == null) {
+                // leave value empty for other binaries
+                strValue = "";
+            }
+        } else {
+            strValue = ValueHelper.serialize(value, false);
+        }
+        return strValue;
+    }
+
     /**
      * Creates a new property.
      * @param name name of the property
@@ -134,7 +199,7 @@ public class DocViewProperty {
         int pos = 0;
         char state = 'b';
         List<String> vals = null;
-        StringBuffer tmp = new StringBuffer();
+        StringBuilder tmp = new StringBuilder();
         int unicode = 0;
         int unicodePos = 0;
         while (pos < value.length()) {
@@ -264,62 +329,51 @@ public class DocViewProperty {
      */
     public static String format(Property prop, boolean sort, boolean useBinaryReferences)
             throws RepositoryException {
-        StringBuffer attrValue = new StringBuffer();
-        int type = prop.getType();
-        if (type == PropertyType.BINARY || isAmbiguous(prop)) {
-            String referenceBinary = null;
-            if (useBinaryReferences && type == PropertyType.BINARY) {
-                Binary bin = prop.getBinary();
-                if (bin != null && bin instanceof ReferenceBinary) {
-                    referenceBinary = ((ReferenceBinary) bin).getReference();
-                }
-            }
+        return fromProperty(prop, sort, useBinaryReferences).format();
+    }
 
-            if (referenceBinary == null) {
-                attrValue.append("{");
-                attrValue.append(PropertyType.nameFromValue(prop.getType()));
-                attrValue.append("}");
+    /** 
+     * Generates string representation of this DocView property.
+     * @return the string representation
+     */
+    String format() {
+        StringBuilder attrValue = new StringBuilder();
+        
+        if (isAmbiguous(type, name)) {
+            final String strType;
+            if (isReferenceProperty) {
+                strType = BINARY_REF;
             } else {
-                attrValue.append("{");
-                attrValue.append(BINARY_REF);
-                attrValue.append("}");
-                attrValue.append(referenceBinary);
+                strType = PropertyType.nameFromValue(type);
             }
+            attrValue.append('{').append(strType).append('}');
         }
-        // only write values for non binaries
-        if (prop.getType() != PropertyType.BINARY) {
-            if (prop.getDefinition().isMultiple()) {
-                attrValue.append('[');
-                Value[] values = prop.getValues();
-                if (sort) {
-                    Arrays.sort(values, ValueComparator.getInstance());
+        if (isMulti) {
+            attrValue.append('[');
+        }
+        for (int i=0;i<values.length;i++) {
+            String value = values[i];
+            if (values.length == 1 && value.length() == 0) {
+                // special case for empty string MV value (JCR-3661)
+                attrValue.append("\\0");
+            } else {
+                if (i > 0) {
+                    attrValue.append(',');
                 }
-                for (int i = 0; i < values.length; i++) {
-                    if (i > 0) {
-                        attrValue.append(',');
-                    }
-                    String strValue = ValueHelper.serialize(values[i], false);
-                    if (values.length == 1 && strValue.length() == 0) {
-                        // special case for empty string MV value (JCR-3661)
-                        attrValue.append("\\0");
-                    } else {
-                        switch (prop.getType()) {
-                            case PropertyType.STRING:
-                            case PropertyType.NAME:
-                            case PropertyType.PATH:
-                                escape(attrValue, strValue, true);
-                                break;
-                            default:
-                                attrValue.append(strValue);
-                        }
-                    }
+                switch (type) {
+                    case PropertyType.STRING:
+                    case PropertyType.NAME:
+                    case PropertyType.PATH:
+                        attrValue.append(escape(value, isMulti));
+                        break;
+                    default:
+                        attrValue.append(value);
                 }
-                attrValue.append(']');
-            } else {
-                String strValue = ValueHelper.serialize(prop.getValue(), false);
-                escape(attrValue, strValue, false);
             }
         }
+        if (isMulti) {
+            attrValue.append(']');
+        }
         return attrValue.toString();
     }
 
@@ -328,8 +382,21 @@ public class DocViewProperty {
      * @param buf buffer to append to
      * @param value value to escape
      * @param isMulti indicates multi value property
+     * @deprecated Rather use {@link #escape(String, boolean))
      */
+    @Deprecated
     protected static void escape(StringBuffer buf, String value, boolean isMulti) {
+        buf.append(escape(value, isMulti));
+    }
+
+    /**
+     * Escapes the value
+     * @param value value to escape
+     * @param isMulti indicates multi value property
+     * @return the escaped value
+     */
+    protected static String escape(String value, boolean isMulti) {
+        StringBuilder buf = new StringBuilder();
         for (int i=0; i<value.length(); i++) {
             char c = value.charAt(i);
             if (c == '\\') {
@@ -348,6 +415,7 @@ public class DocViewProperty {
                 buf.append(c);
             }
         }
+        return buf.toString();
     }
     
     /**
@@ -358,9 +426,24 @@ public class DocViewProperty {
      * @param prop the property
      * @return type
      * @throws RepositoryException if a repository error occurs
+     * @deprecated use {@link #isAmbiguous(int,String)} instead.
      */
+    @Deprecated
     public static boolean isAmbiguous(Property prop) throws RepositoryException {
-        return prop.getType() != PropertyType.STRING && !UNAMBIGOUS.contains(prop.getName());
+        return isAmbiguous(prop.getType(), prop.getName());
+    }
+
+    /**
+     * Checks if the type of the given property is ambiguous in respect to it's
+     * property definition. the current implementation just checks some well
+     * known properties.
+     *
+     * @param type the type
+     * @param name the name
+     * @return {@code true} if type information should be emitted, otherwise {@code false}
+     */
+    private static boolean isAmbiguous(int type, String name) {
+        return type != PropertyType.STRING && !UNAMBIGOUS.contains(name);
     }
 
     /**
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/package-info.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/package-info.java
index 863a0c3..c40fa9a 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/package-info.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/package-info.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-@Version("2.6.1")
+@Version("2.7.0")
 package org.apache.jackrabbit.vault.util;
 
 import org.osgi.annotation.versioning.Version;
\ No newline at end of file
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/util/DocViewPropertyTest.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/util/DocViewPropertyTest.java
index e69fb8e..71337e6 100644
--- a/vault-core/src/test/java/org/apache/jackrabbit/vault/util/DocViewPropertyTest.java
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/util/DocViewPropertyTest.java
@@ -148,11 +148,11 @@ public class DocViewPropertyTest {
         Value value = Mockito.mock(Value.class);
 
         Mockito.when(value.getString()).thenReturn("");
+        Mockito.when(value.getType()).thenReturn(PropertyType.STRING);
         Value[] values = new Value[]{value};
         PropertyDefinition pd = Mockito.mock(PropertyDefinition.class);
         Mockito.when(pd.isMultiple()).thenReturn(true);
 
-        Mockito.when(p.getType()).thenReturn(PropertyType.STRING);
         Mockito.when(p.getName()).thenReturn("foo");
         Mockito.when(p.getValues()).thenReturn(values);
         Mockito.when(p.getDefinition()).thenReturn(pd);
@@ -171,11 +171,11 @@ public class DocViewPropertyTest {
         Value value = Mockito.mock(Value.class);
 
         Mockito.when(value.getString()).thenReturn("false");
+        Mockito.when(value.getType()).thenReturn(PropertyType.BOOLEAN);
         Value[] values = new Value[]{value};
         PropertyDefinition pd = Mockito.mock(PropertyDefinition.class);
         Mockito.when(pd.isMultiple()).thenReturn(true);
 
-        Mockito.when(p.getType()).thenReturn(PropertyType.BOOLEAN);
         Mockito.when(p.getName()).thenReturn("foo");
         Mockito.when(p.getValues()).thenReturn(values);
         Mockito.when(p.getDefinition()).thenReturn(pd);
@@ -204,9 +204,7 @@ public class DocViewPropertyTest {
     }
 
     private void assertEscaped(String original, String expected, boolean multi) {
-        StringBuffer buf = new StringBuffer();
-        DocViewProperty.escape(buf, original, multi);
-        Assert.assertEquals(expected, buf.toString());
+        Assert.assertEquals(expected, DocViewProperty.escape(original, multi));
     }
 
     private void assertEquals(DocViewProperty p, boolean multi, int type, String... values) {