You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2013/03/27 12:43:41 UTC

svn commit: r1461538 - in /jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr: NodeImpl.java PropertyImpl.java

Author: mduerig
Date: Wed Mar 27 11:43:41 2013
New Revision: 1461538

URL: http://svn.apache.org/r1461538
Log:
OAK-672: Avoid JCR APIs calling other JCR APIs
OAK-662: Reduce boilerplate code in JCR impl methods
Align NodeImpl.setProperty and PropertyImpl.setValue implementations

Modified:
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1461538&r1=1461537&r2=1461538&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Wed Mar 27 11:43:41 2013
@@ -339,19 +339,7 @@ public class NodeImpl<T extends NodeDele
     public Property setProperty(String name, Value[] values)
             throws RepositoryException {
         if (values != null) {
-            int type = UNDEFINED;
-            for (Value value : values) {
-                if (value != null) {
-                    if (type == UNDEFINED) {
-                        type = value.getType();
-                    } else if (value.getType() != type) {
-                        throw new ValueFormatException(
-                                "All values of a multi-valued property"
-                                        + " must be of the same type");
-                    }
-                }
-            }
-            return internalSetProperty(name, values, type, false);
+            return internalSetProperty(name, values, PropertyImpl.getType(values), false);
         } else {
             return internalRemoveProperty(name);
         }
@@ -1342,29 +1330,6 @@ public class NodeImpl<T extends NodeDele
                 });
     }
 
-    private static int getTargetType(Value value, PropertyDefinition definition) {
-        if (definition.getRequiredType() == PropertyType.UNDEFINED) {
-            return value.getType();
-        } else {
-            return definition.getRequiredType();
-        }
-    }
-
-    private static int getTargetType(Value[] values, PropertyDefinition definition) {
-        if (definition.getRequiredType() == PropertyType.UNDEFINED) {
-            if (values.length != 0) {
-                for (Value v : values) {
-                    if (v != null) {
-                        return v.getType();
-                    }
-                }
-            }
-            return PropertyType.STRING;
-        } else {
-            return definition.getRequiredType();
-        }
-    }
-
     private void autoCreateItems() throws RepositoryException {
         EffectiveNodeType effective = getEffectiveNodeType();
         for (PropertyDefinition pd : effective.getAutoCreatePropertyDefinitions()) {
@@ -1486,17 +1451,18 @@ public class NodeImpl<T extends NodeDele
                 // TODO: Avoid extra JCR method calls (OAK-672)
                 PropertyDefinition definition = getDefinitionProvider().getDefinition(
                         dlg.getTree(), state, exactTypeMatch);
+
                 checkProtected(definition);
                 if (definition.isMultiple()) {
                     throw new ValueFormatException(
                             "Cannot set single value to multivalued property");
                 }
 
-                int targetType = getTargetType(value, definition);
+                int targetType = PropertyImpl.getType(definition, value.getType());
                 if (targetType != value.getType()) {
                     state = PropertyStates.createProperty(
                             oakName, ValueHelper.convert(
-                                    value, targetType, getValueFactory()));
+                            value, targetType, getValueFactory()));
                 }
 
                 return new PropertyImpl(dlg.setProperty(state), sessionContext);
@@ -1509,7 +1475,7 @@ public class NodeImpl<T extends NodeDele
             final int type, final boolean exactTypeMatch)
             throws RepositoryException {
         final String oakName = getOakPathOrThrow(checkNotNull(jcrName));
-        final Value[] nonNullValues = compact(checkNotNull(values));
+        final Value[] nonNullValues = PropertyImpl.compact(checkNotNull(values));
         return perform(new ItemWriteOperation<Property>() {
             @Override
             public Property perform() throws RepositoryException {
@@ -1525,7 +1491,7 @@ public class NodeImpl<T extends NodeDele
                             "Cannot set value array to single value property");
                 }
 
-                int targetType = getTargetType(nonNullValues, definition);
+                int targetType = PropertyImpl.getType(definition, type);
                 if (targetType != type) {
                     state = PropertyStates.createProperty(
                             oakName, Arrays.asList(ValueHelper.convert(
@@ -1559,30 +1525,4 @@ public class NodeImpl<T extends NodeDele
         });
     }
 
-    /**
-     * Removes all {@code null} values from the given array.
-     *
-     * @param values value array
-     * @return value array without {@code null} entries
-     */
-    private static Value[] compact(Value[] values) {
-        int n = 0;
-        for (Value value : values) {
-            if (value != null) {
-                n++;
-            }
-        }
-        if (n == values.length) {
-            return values;
-        } else {
-            Value[] nonNullValues = new Value[n];
-            for (int i = 0, j = 0; i < values.length; i++) {
-                if (values[i] != null) {
-                    nonNullValues[j++] = values[i];
-                }
-            }
-            return nonNullValues;
-        }
-    }
-
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java?rev=1461538&r1=1461537&r2=1461538&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java Wed Mar 27 11:43:41 2013
@@ -16,11 +16,11 @@
  */
 package org.apache.jackrabbit.oak.jcr;
 
-import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.jcr.PropertyType.UNDEFINED;
 
 import java.io.InputStream;
 import java.math.BigDecimal;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.List;
@@ -39,8 +39,7 @@ import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
 import javax.jcr.nodetype.PropertyDefinition;
 
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree.Status;
 import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
 import org.apache.jackrabbit.oak.jcr.delegate.PropertyDelegate;
@@ -54,10 +53,6 @@ import org.slf4j.LoggerFactory;
  * TODO document
  */
 public class PropertyImpl extends ItemImpl<PropertyDelegate> implements Property {
-
-    /**
-     * logger instance
-     */
     private static final Logger log = LoggerFactory.getLogger(PropertyImpl.class);
 
     private static final Value[] NO_VALUES = new Value[0];
@@ -68,17 +63,11 @@ public class PropertyImpl extends ItemIm
 
     //---------------------------------------------------------------< Item >---
 
-    /**
-     * @see javax.jcr.Item#isNode()
-     */
     @Override
     public boolean isNode() {
         return false;
     }
 
-    /**
-     * @see javax.jcr.Item#getParent()
-     */
     @Override
     @Nonnull
     public Node getParent() throws RepositoryException {
@@ -95,9 +84,6 @@ public class PropertyImpl extends ItemIm
         });
     }
 
-    /**
-     * @see javax.jcr.Item#isNew()
-     */
     @Override
     public boolean isNew() {
         return safePerform(new ItemReadOperation<Boolean>() {
@@ -108,9 +94,6 @@ public class PropertyImpl extends ItemIm
         });
     }
 
-    /**
-     * @see javax.jcr.Item#isModified() ()
-     */
     @Override
     public boolean isModified() {
         return safePerform(new ItemReadOperation<Boolean>() {
@@ -121,9 +104,6 @@ public class PropertyImpl extends ItemIm
         });
     }
 
-    /**
-     * @see javax.jcr.Item#isNew()
-     */
     @Override
     public void remove() throws RepositoryException {
         perform(new ItemWriteOperation<Void>() {
@@ -135,9 +115,6 @@ public class PropertyImpl extends ItemIm
         });
     }
 
-    /**
-     * @see javax.jcr.Item#accept(javax.jcr.ItemVisitor)
-     */
     @Override
     public void accept(ItemVisitor visitor) throws RepositoryException {
         checkStatus();
@@ -146,192 +123,100 @@ public class PropertyImpl extends ItemIm
 
     //-----------------------------------------------------------< Property >---
 
-    /**
-     * @see Property#setValue(Value)
-     */
     @Override
     public void setValue(Value value) throws RepositoryException {
-        checkStatus();
-
-        int valueType = (value != null) ? value.getType() : PropertyType.UNDEFINED;
-        int reqType = getRequiredType(valueType);
-        setValue(value, reqType);
+        if (value == null) {
+            internalRemove();
+        } else {
+            internalSetValue(value);
+        }
     }
 
-    /**
-     * @see Property#setValue(Value[])
-     */
     @Override
     public void setValue(final Value[] values) throws RepositoryException {
-        perform(new ItemWriteOperation<Void>() {
-            @Override
-            public Void perform() throws RepositoryException {
-                // assert equal types for all values entries
-                int valueType = PropertyType.UNDEFINED;
-                if (values != null) {
-                    for (Value value : values) {
-                        if (value == null) {
-                            // skip null values as those will be purged later
-                            continue;
-                        }
-                        if (valueType == PropertyType.UNDEFINED) {
-                            valueType = value.getType();
-                        } else if (valueType != value.getType()) {
-                            String msg = "Inhomogeneous type of values (" + this + ')';
-                            log.debug(msg);
-                            throw new ValueFormatException(msg);
-                        }
-                    }
-                }
-
-                int reqType = getRequiredType(valueType);
-                setValues(values, reqType);
-                return null;
-            }
-        });
+        if (values == null) {
+            internalRemove();
+        } else {
+            internalSetValues(values, getType(values));
+        }
     }
 
-    /**
-     * @see Property#setValue(String)
-     */
     @Override
     public void setValue(String value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.STRING);
         if (value == null) {
-            setValue(null, reqType);
+            internalRemove();
         } else {
-            setValue(getValueFactory().createValue(value), reqType);
+            internalSetValue(getValueFactory().createValue(value));
         }
     }
 
-    /**
-     * @see Property#setValue(String[])
-     */
     @Override
     public void setValue(String[] values) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.STRING);
         if (values == null) {
-            setValues(null, reqType);
+            internalRemove();
         } else {
-            List<Value> vs = new ArrayList<Value>(values.length);
-            for (String value : values) {
-                if (value != null) {
-                    vs.add(getValueFactory().createValue(value));
-                }
-            }
-            setValues(vs.toArray(new Value[vs.size()]), reqType);
+            Value[] vs = ValueHelper.convert(values, PropertyType.STRING, getValueFactory());
+            internalSetValues(vs, UNDEFINED);
         }
     }
 
-    /**
-     * @see Property#setValue(InputStream)
-     */
     @Override
     public void setValue(InputStream value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.BINARY);
         if (value == null) {
-            setValue(null, reqType);
+            internalRemove();
         } else {
-            setValue(getValueFactory().createValue(value), reqType);
+            internalSetValue(getValueFactory().createValue(value));
         }
     }
 
-    /**
-     * @see Property#setValue(Binary)
-     */
     @Override
     public void setValue(Binary value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.BINARY);
         if (value == null) {
-            setValue(null, reqType);
+            internalRemove();
         } else {
-            setValue(getValueFactory().createValue(value), reqType);
+            internalSetValue(getValueFactory().createValue(value));
         }
     }
 
-    /**
-     * @see Property#setValue(long)
-     */
     @Override
     public void setValue(long value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.LONG);
-        setValue(getValueFactory().createValue(value), reqType);
+        internalSetValue(getValueFactory().createValue(value));
     }
 
-    /**
-     * @see Property#setValue(double)
-     */
     @Override
     public void setValue(double value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.DOUBLE);
-        setValue(getValueFactory().createValue(value), reqType);
+        internalSetValue(getValueFactory().createValue(value));
     }
 
-    /**
-     * @see Property#setValue(BigDecimal)
-     */
     @Override
     public void setValue(BigDecimal value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.DECIMAL);
         if (value == null) {
-            setValue(null, reqType);
+            internalRemove();
         } else {
-            setValue(getValueFactory().createValue(value), reqType);
+            internalSetValue(getValueFactory().createValue(value));
         }
     }
 
-    /**
-     * @see Property#setValue(Calendar)
-     */
     @Override
     public void setValue(Calendar value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.DATE);
         if (value == null) {
-            setValue(null, reqType);
+            internalRemove();
         } else {
-            setValue(getValueFactory().createValue(value), reqType);
+            internalSetValue(getValueFactory().createValue(value));
         }
     }
 
-    /**
-     * @see Property#setValue(boolean)
-     */
     @Override
     public void setValue(boolean value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.BOOLEAN);
-        setValue(getValueFactory().createValue(value), reqType);
+        internalSetValue(getValueFactory().createValue(value));
     }
 
-    /**
-     * @see Property#setValue(javax.jcr.Node)
-     */
     @Override
     public void setValue(Node value) throws RepositoryException {
-        checkStatus();
-
-        int reqType = getRequiredType(PropertyType.REFERENCE);
         if (value == null) {
-            setValue(null, reqType);
+            internalRemove();
         } else {
-            setValue(getValueFactory().createValue(value), reqType);
+            internalSetValue(getValueFactory().createValue(value));
         }
     }
 
@@ -357,18 +242,12 @@ public class PropertyImpl extends ItemIm
         }).toArray(NO_VALUES);
     }
 
-    /**
-     * @see Property#getString()
-     */
     @Override
     @Nonnull
     public String getString() throws RepositoryException {
         return getValue().getString();
     }
 
-    /**
-     * @see Property#getStream()
-     */
     @SuppressWarnings("deprecation")
     @Override
     @Nonnull
@@ -376,60 +255,39 @@ public class PropertyImpl extends ItemIm
         return getValue().getStream();
     }
 
-    /**
-     * @see javax.jcr.Property#getBinary()
-     */
     @Override
     @Nonnull
     public Binary getBinary() throws RepositoryException {
         return getValue().getBinary();
     }
 
-    /**
-     * @see Property#getLong()
-     */
     @Override
     public long getLong() throws RepositoryException {
         return getValue().getLong();
     }
 
-    /**
-     * @see Property#getDouble()
-     */
     @Override
     public double getDouble() throws RepositoryException {
         return getValue().getDouble();
     }
 
-    /**
-     * @see Property#getDecimal()
-     */
     @Override
     @Nonnull
     public BigDecimal getDecimal() throws RepositoryException {
         return getValue().getDecimal();
     }
 
-    /**
-     * @see Property#getDate()
-     */
     @Override
     @Nonnull
     public Calendar getDate() throws RepositoryException {
         return getValue().getDate();
     }
 
-    /**
-     * @see Property#getBoolean()
-     */
     @Override
     public boolean getBoolean() throws RepositoryException {
         return getValue().getBoolean();
     }
 
-    /**
-     * @see javax.jcr.Property#getNode()
-     */
     @Override
     @Nonnull
     public Node getNode() throws RepositoryException {
@@ -482,9 +340,6 @@ public class PropertyImpl extends ItemIm
         });
     }
 
-    /**
-     * @see javax.jcr.Property#getProperty()
-     */
     @Override
     @Nonnull
     public Property getProperty() throws RepositoryException {
@@ -503,17 +358,11 @@ public class PropertyImpl extends ItemIm
         });
     }
 
-    /**
-     * @see javax.jcr.Property#getLength()
-     */
     @Override
     public long getLength() throws RepositoryException {
         return getLength(getValue());
     }
 
-    /**
-     * @see javax.jcr.Property#getLengths()
-     */
     @Override
     @Nonnull
     public long[] getLengths() throws RepositoryException {
@@ -538,9 +387,6 @@ public class PropertyImpl extends ItemIm
         });
     }
 
-    /**
-     * @see javax.jcr.Property#getType()
-     */
     @Override
     public int getType() throws RepositoryException {
         return perform(new ItemReadOperation<Integer>() {
@@ -550,7 +396,7 @@ public class PropertyImpl extends ItemIm
                     Value[] values = getValues();
                     if (values.length == 0) {
                         // retrieve the type from the property definition
-                        return getRequiredType(PropertyType.UNDEFINED);
+                        return getType(getDefinition(), PropertyType.UNDEFINED);
                     } else {
                         return values[0].getType();
                     }
@@ -571,85 +417,156 @@ public class PropertyImpl extends ItemIm
         });
     }
 
-    //------------------------------------------------------------< private >---
+    //------------------------------------------------------------< internal >---
 
     /**
-     * Return the length of the specified JCR value object.
+     * Determine the {@link javax.jcr.PropertyType} of the passed values if all are of
+     * the same type.
      *
-     * @param value The value.
-     * @return The length of the given value.
-     * @throws RepositoryException If an error occurs.
-     */
-    private static long getLength(Value value) throws RepositoryException {
-        if (value.getType() == PropertyType.BINARY) {
-            return value.getBinary().getSize();
-        } else {
-            return value.getString().length();
+     * @param values array of values of the same type
+     * @return  {@link javax.jcr.PropertyType#UNDEFINED} if {@code values} is empty,
+     *          {@code values[0].getType()} otherwise.
+     * @throws javax.jcr.ValueFormatException  if not all {@code values} are of the same type
+     */
+    static int getType(Value[] values) throws ValueFormatException {
+        int type = UNDEFINED;
+        for (Value value : values) {
+            if (value != null) {
+                if (type == UNDEFINED) {
+                    type = value.getType();
+                } else if (value.getType() != type) {
+                    throw new ValueFormatException(
+                            "All values of a multi-valued property must be of the same type");
+                }
+            }
         }
+        return type;
     }
 
     /**
+     * Determine property type from property definition and default to
+     * {@code defaultType} in the case of {@link PropertyType#UNDEFINED}.
+     *
+     * @param definition
      * @param defaultType
-     * @return the required type for this property.
-     * @throws javax.jcr.RepositoryException
+     * @return the type determined from the property definition
      */
-    private int getRequiredType(int defaultType) throws RepositoryException {
-        // check type according to definition of this property
-        int reqType = getDefinition().getRequiredType();
-        if (reqType == PropertyType.UNDEFINED) {
-            if (defaultType == PropertyType.UNDEFINED) {
-                reqType = PropertyType.STRING;
-            } else {
-                reqType = defaultType;
-            }
+    static int getType(PropertyDefinition definition, int defaultType) {
+        if (definition.getRequiredType() == PropertyType.UNDEFINED) {
+            return defaultType == PropertyType.UNDEFINED ? PropertyType.STRING : defaultType;
+        } else {
+            return definition.getRequiredType();
         }
-        return reqType;
     }
 
     /**
-     * @param value
-     * @param requiredType
-     * @throws RepositoryException
+     * Removes all {@code null} values from the given array.
+     *
+     * @param values value array
+     * @return value array without {@code null} entries
      */
-    private void setValue(Value value, int requiredType) throws RepositoryException {
-        checkArgument(requiredType != PropertyType.UNDEFINED);
-        checkProtected();
-
-        // TODO check again if definition validation should be respected here.
-        if (isMultiple()) {
-            throw new ValueFormatException("Attempt to set a single value to multi-valued property.");
+    static Value[] compact(Value[] values) {
+        int n = 0;
+        for (Value value : values) {
+            if (value != null) {
+                n++;
+            }
         }
-        if (value == null) {
-            dlg.remove();
+        if (n == values.length) {
+            return values;
         } else {
-            Value targetValue = ValueHelper.convert(value, requiredType, getValueFactory());
-            dlg.setState(PropertyStates.createProperty(dlg.getName(), targetValue));
+            Value[] nonNullValues = new Value[n];
+            for (int i = 0, j = 0; i < values.length; i++) {
+                if (values[i] != null) {
+                    nonNullValues[j++] = values[i];
+                }
+            }
+            return nonNullValues;
         }
     }
 
     /**
-     * @param values
-     * @param requiredType
-     * @throws RepositoryException
+     * Return the length of the specified JCR value object.
+     *
+     * @param value The value.
+     * @return The length of the given value.
+     * @throws RepositoryException If an error occurs.
      */
-    private void setValues(Value[] values, int requiredType) throws RepositoryException {
-        checkArgument(requiredType != PropertyType.UNDEFINED);
-        checkProtected();
-
-        // TODO check again if definition validation should be respected here.
-        if (!isMultiple()) {
-            throw new ValueFormatException("Attempt to set multiple values to single valued property.");
-        }
-        if (values == null) {
-            dlg.remove();
+    private static long getLength(Value value) throws RepositoryException {
+        if (value.getType() == PropertyType.BINARY) {
+            return value.getBinary().getSize();
         } else {
-            Value[] targetValues = ValueHelper.convert(values, requiredType, getValueFactory());
-            Iterable<Value> nonNullValues = Iterables.filter(
-                    Arrays.asList(targetValues),
-                    Predicates.notNull());
-
-            dlg.setState(PropertyStates.createProperty(dlg.getName(), nonNullValues));
+            return value.getString().length();
         }
     }
 
+    private void internalRemove() throws RepositoryException {
+        perform(new ItemWriteOperation<Void>() {
+            @Override
+            protected Void perform() throws RepositoryException {
+                dlg.remove();
+                return null;
+            }
+        });
+    }
+
+    private void internalSetValue(@Nonnull final Value value)
+            throws RepositoryException {
+        checkNotNull(value);
+        perform(new ItemWriteOperation<Void>() {
+            @Override
+            protected Void perform() throws RepositoryException {
+                // TODO: Avoid extra JCR method calls (OAK-672)
+                PropertyDefinition definition = getDefinitionProvider().getDefinition(
+                        dlg.getParent().getTree(), dlg.getPropertyState(), true);
+
+                if (definition.isMultiple()) {
+                    throw new ValueFormatException("Cannot set single value to multivalued property");
+                }
+
+                PropertyState state;
+                int targetType = getType(definition, value.getType());
+                if (targetType != value.getType()) {
+                    state = PropertyStates.createProperty(
+                            dlg.getName(), ValueHelper.convert(
+                            value, targetType, getValueFactory()));
+                } else {
+                    state = PropertyStates.createProperty(dlg.getName(), value);
+                }
+
+                dlg.setState(state);
+                return null;
+            }
+        });
+    }
+
+    private void internalSetValues(@Nonnull final Value[] values, final int type) throws RepositoryException {
+        final Value[] nonNullValues = compact(checkNotNull(values));
+        perform(new ItemWriteOperation<Void>() {
+            @Override
+            protected Void perform() throws RepositoryException {
+                // TODO: Avoid extra JCR method calls (OAK-672)
+                PropertyDefinition definition = getDefinitionProvider().getDefinition(
+                        dlg.getParent().getTree(), dlg.getPropertyState(), true);
+
+                if (!definition.isMultiple()) {
+                    throw new ValueFormatException("Cannot set value array to single value property");
+                }
+
+                PropertyState state;
+                int targetType = getType(definition, type);
+                if (targetType != type) {
+                    state = PropertyStates.createProperty(
+                            dlg.getName(), Arrays.asList(ValueHelper.convert(
+                            nonNullValues, targetType, getValueFactory())));
+                } else {
+                    state = PropertyStates.createProperty(dlg.getName(), Arrays.asList(nonNullValues));
+                }
+
+                dlg.setState(state);
+                return null;
+            }
+        });
+    }
+
 }
\ No newline at end of file