Author: rombert
Date: Mon Sep 9 14:44:24 2013
New Revision: 1521147
URL: http://svn.apache.org/r1521147
Log:
SLING-2989 - [Tooling] integrate with vlt once available
Support sync of multi-valued properties to the repository. As before,
Name, Path, Reference and WeakReference property types are not
supported.
Added:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/serialization/multivalued-properties-content.xml
(with props)
Removed:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/serialization/multiple-properties-connect.xml
Modified:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandlerTest.java
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/ConversionUtils.java
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandler.java
Modified:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandlerTest.java
URL:
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandlerTest.java?rev=1521147&r1=1521146&r2=1521147&view=diff
==============================================================================
---
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandlerTest.java
(original)
+++
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandlerTest.java
Mon Sep 9 14:44:24 2013
@@ -17,8 +17,8 @@
package org.apache.sling.ide.impl.vlt.serialization;
import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.array;
import static org.hamcrest.Matchers.hasEntry;
-import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import java.io.IOException;
@@ -30,6 +30,10 @@ import javax.xml.parsers.ParserConfigura
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
import org.junit.Ignore;
import org.junit.Test;
import org.xml.sax.InputSource;
@@ -49,13 +53,11 @@ public class ContentXmlHandlerTest {
assertThat("properties[indexed]", properties, hasEntry("indexed",
(Object) Boolean.TRUE));
assertThat("properties[indexRatio]", properties,
hasEntry("indexRatio", (Object) Double.valueOf(2.54)));
assertThat("properties[indexDuration]", properties,
hasEntry("indexDuration", (Object) BigDecimal.valueOf(500)));
- assertThat("properties[lastIndexTime]", properties,
hasEntry(is("lastIndexTime"), notNullValue()));
+ assertThat("properties[lastIndexTime]", (Calendar)
properties.get("lastIndexTime"),
+ is(millis(1378292400000l)));
assertThat("properties[lastIndexId]", properties,
hasEntry("lastIndexId", (Object)
Long.valueOf(7293120000000l)));
- Calendar lastIndexTime = (Calendar) properties.get("lastIndexTime");
- assertThat(lastIndexTime.getTimeInMillis(), is(1378292400000l));
-
}
private Map<String, Object> parseContentXmlFile(String fileName) throws
ParserConfigurationException, SAXException,
@@ -99,4 +101,50 @@ public class ContentXmlHandlerTest {
assertThat("properties.size", properties.size(), is(3));
}
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void parseMultiValuedProperties() throws
ParserConfigurationException, SAXException, IOException {
+
+ Map<String, Object> properties =
parseContentXmlFile("multivalued-properties-content.xml");
+
+ assertThat("properties.size", properties.size(), is(7));
+ assertThat("properties[values]", (String[]) properties.get("values"),
+ Matchers.is(new String[] { "first", "second" }));
+ assertThat("properties[decimals]", (BigDecimal[])
properties.get("decimals"),
+ Matchers.is(new BigDecimal[] { new BigDecimal("5.10"), new
BigDecimal("5.11") }));
+ assertThat("properties[doubles]", (Double[]) properties.get("doubles"),
+ Matchers.is(new Double[] { new Double("5.1"), new
Double("7.5"), new Double("9.0") }));
+ assertThat("properties[flags]", (Boolean[]) properties.get("flags"),
+ Matchers.is(new Boolean[] { Boolean.FALSE, Boolean.TRUE }));
+ assertThat("properties[longs]", (Long[]) properties.get("longs"),
+ Matchers.is(new Long[] { Long.valueOf(15), Long.valueOf(25)
}));
+ assertThat("properties[dates]", (Calendar[]) properties.get("dates"),
array(
+ millis(1377982800000l), millis(1378242000000l)));
+ }
+
+ private static Matcher<Calendar> millis(long millis) {
+
+ return new CalendarTimeInMillisMatcher(millis);
+ }
+
+ static class CalendarTimeInMillisMatcher extends TypeSafeMatcher<Calendar>
{
+
+ private final long timeInMillis;
+
+ private CalendarTimeInMillisMatcher(long timeInMillis) {
+ this.timeInMillis = timeInMillis;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("getTimeInMillis() does not equal
").appendValue(timeInMillis);
+ }
+
+ @Override
+ protected boolean matchesSafely(Calendar item) {
+ return timeInMillis == item.getTimeInMillis();
+ }
+
+ }
}
Added:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/serialization/multivalued-properties-content.xml
URL:
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/serialization/multivalued-properties-content.xml?rev=1521147&view=auto
==============================================================================
---
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/serialization/multivalued-properties-content.xml
(added)
+++
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/serialization/multivalued-properties-content.xml
Mon Sep 9 14:44:24 2013
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+ jcr:primaryType="nt:unstructured"
+ dates="{Date}[2013-09-01T00:00:00.000+03:00,2013-09-04T00:00:00.000+03:00]"
+ decimals="{Decimal}[5.10,5.11]"
+ doubles="{Double}[5.1,7.5,9.0]"
+ flags="{Boolean}[false,true]"
+ longs="{Long}[15,25]"
+ values="[first,second]"/>
\ No newline at end of file
Propchange:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/serialization/multivalued-properties-content.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/serialization/multivalued-properties-content.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Modified:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/ConversionUtils.java
URL:
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/ConversionUtils.java?rev=1521147&r1=1521146&r2=1521147&view=diff
==============================================================================
---
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/ConversionUtils.java
(original)
+++
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/ConversionUtils.java
Mon Sep 9 14:44:24 2013
@@ -16,6 +16,9 @@
*/
package org.apache.sling.ide.impl.vlt;
+import java.math.BigDecimal;
+import java.util.Calendar;
+
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
@@ -30,23 +33,43 @@ public abstract class ConversionUtils {
// TODO - handle isMultiple() == true
switch (property.getType()) {
case PropertyType.BOOLEAN:
- propertyValue = property.getBoolean();
+ if (property.isMultiple()) {
+ propertyValue = toBooleanArray(property.getValues());
+ } else {
+ propertyValue = property.getBoolean();
+ }
break;
case PropertyType.DATE:
- propertyValue = property.getDate();
+ if (property.isMultiple()) {
+ propertyValue = toCalendarArray(property.getValues());
+ } else {
+ propertyValue = property.getDate();
+ }
break;
case PropertyType.DECIMAL:
- propertyValue = property.getDecimal();
+ if (property.isMultiple()) {
+ propertyValue = toDecimalArray(property.getValues());
+ } else {
+ propertyValue = property.getDecimal();
+ }
break;
case PropertyType.DOUBLE:
- propertyValue = property.getDouble();
+ if (property.isMultiple()) {
+ propertyValue = toDoubleArray(property.getValues());
+ } else {
+ propertyValue = property.getDouble();
+ }
break;
case PropertyType.LONG:
- propertyValue = property.getLong();
+ if (property.isMultiple()) {
+ propertyValue = toLongArray(property.getValues());
+ } else {
+ propertyValue = property.getLong();
+ }
break;
case PropertyType.PATH:
@@ -83,6 +106,56 @@ public abstract class ConversionUtils {
return ret;
}
+ private static Boolean[] toBooleanArray(Value[] values) throws
RepositoryException {
+
+ Boolean[] ret = new Boolean[values.length];
+ for (int i = 0; i < values.length; i++) {
+ ret[i] = values[i].getBoolean();
+ }
+
+ return ret;
+ }
+
+ private static Calendar[] toCalendarArray(Value[] values) throws
RepositoryException {
+
+ Calendar[] ret = new Calendar[values.length];
+ for (int i = 0; i < values.length; i++) {
+ ret[i] = values[i].getDate();
+ }
+
+ return ret;
+ }
+
+ private static BigDecimal[] toDecimalArray(Value[] values) throws
RepositoryException {
+
+ BigDecimal[] ret = new BigDecimal[values.length];
+ for (int i = 0; i < values.length; i++) {
+ ret[i] = values[i].getDecimal();
+ }
+
+ return ret;
+ }
+
+ private static Double[] toDoubleArray(Value[] values) throws
RepositoryException {
+
+ Double[] ret = new Double[values.length];
+ for (int i = 0; i < values.length; i++) {
+ ret[i] = values[i].getDouble();
+ }
+
+ return ret;
+ }
+
+ private static Long[] toLongArray(Value[] values) throws
RepositoryException {
+
+ Long[] ret = new Long[values.length];
+ for (int i = 0; i < values.length; i++) {
+ ret[i] = values[i].getLong();
+ }
+
+ return ret;
+ }
+
private ConversionUtils() {
}
Modified:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java
URL:
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java?rev=1521147&r1=1521146&r2=1521147&view=diff
==============================================================================
---
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java
(original)
+++
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java
Mon Sep 9 14:44:24 2013
@@ -27,6 +27,7 @@ import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import javax.jcr.Value;
import org.apache.jackrabbit.vault.util.PathUtil;
import org.apache.sling.ide.transport.FileInfo;
@@ -50,7 +51,6 @@ public class UpdateNodePropertiesCommand
Node node = session.getNode(getPath());
// TODO - review for completeness and filevault compatibility
- // TODO - multi-valued properties
for (Map.Entry<String, Object> entry : serializationData.entrySet()) {
if (node.hasProperty(entry.getKey())) {
@@ -59,26 +59,35 @@ public class UpdateNodePropertiesCommand
if (prop.getDefinition().isProtected()) {
continue;
}
+ }
- if (entry.getValue() instanceof String) {
- node.setProperty(entry.getKey(), (String)
entry.getValue());
- } else if (entry.getValue() instanceof Boolean) {
- node.setProperty(entry.getKey(), (Boolean)
entry.getValue());
- } else if (entry.getValue() instanceof Calendar) {
- node.setProperty(entry.getKey(), (Calendar)
entry.getValue());
- } else if (entry.getValue() instanceof Double) {
- node.setProperty(entry.getKey(), (Double)
entry.getValue());
- } else if (entry.getValue() instanceof BigDecimal) {
- node.setProperty(entry.getKey(), (BigDecimal)
entry.getValue());
- } else if (entry.getValue() instanceof Double) {
- node.setProperty(entry.getKey(), (Double)
entry.getValue());
- } else if (entry.getValue() instanceof Long) {
- node.setProperty(entry.getKey(), (Long) entry.getValue());
- } else {
- throw new IllegalArgumentException("Unable to handle value
of type '"
- + entry.getValue().getClass().getName() + "' for
property '" + entry.getKey() + "'");
- }
-
+ if (entry.getValue() instanceof String) {
+ node.setProperty(entry.getKey(), (String) entry.getValue());
+ } else if (entry.getValue() instanceof String[]) {
+ node.setProperty(entry.getKey(), (String[]) entry.getValue());
+ } else if (entry.getValue() instanceof Boolean) {
+ node.setProperty(entry.getKey(), (Boolean) entry.getValue());
+ } else if (entry.getValue() instanceof Boolean[]) {
+ node.setProperty(entry.getKey(), toValueArray((Boolean[])
entry.getValue(), session));
+ } else if (entry.getValue() instanceof Calendar) {
+ node.setProperty(entry.getKey(), (Calendar) entry.getValue());
+ } else if (entry.getValue() instanceof Calendar[]) {
+ node.setProperty(entry.getKey(), toValueArray((Calendar[])
entry.getValue(), session));
+ } else if (entry.getValue() instanceof Double) {
+ node.setProperty(entry.getKey(), (Double) entry.getValue());
+ } else if (entry.getValue() instanceof Double[]) {
+ node.setProperty(entry.getKey(), toValueArray((Double[])
entry.getValue(), session));
+ } else if (entry.getValue() instanceof BigDecimal) {
+ node.setProperty(entry.getKey(), (BigDecimal)
entry.getValue());
+ } else if (entry.getValue() instanceof BigDecimal[]) {
+ node.setProperty(entry.getKey(), toValueArray((BigDecimal[])
entry.getValue(), session));
+ } else if (entry.getValue() instanceof Long) {
+ node.setProperty(entry.getKey(), (Long) entry.getValue());
+ } else if (entry.getValue() instanceof Long[]) {
+ node.setProperty(entry.getKey(), toValueArray((Long[])
entry.getValue(), session));
+ } else {
+ throw new IllegalArgumentException("Unable to handle value of
type '"
+ + entry.getValue().getClass().getName() + "' for
property '" + entry.getKey() + "'");
}
}
@@ -86,4 +95,59 @@ public class UpdateNodePropertiesCommand
}
+ private Value[] toValueArray(Boolean[] booleans, Session session) throws
RepositoryException {
+
+ Value[] values = new Value[booleans.length];
+
+ for (int i = 0; i < booleans.length; i++) {
+ values[i] = session.getValueFactory().createValue(booleans[i]);
+ }
+
+ return values;
+ }
+
+ private Value[] toValueArray(Calendar[] calendars, Session session) throws
RepositoryException {
+
+ Value[] values = new Value[calendars.length];
+
+ for (int i = 0; i < calendars.length; i++) {
+ values[i] = session.getValueFactory().createValue(calendars[i]);
+ }
+
+ return values;
+ }
+
+ private Value[] toValueArray(Double[] doubles, Session session) throws
RepositoryException {
+
+ Value[] values = new Value[doubles.length];
+
+ for (int i = 0; i < doubles.length; i++) {
+ values[i] = session.getValueFactory().createValue(doubles[i]);
+ }
+
+ return values;
+ }
+
+ private Value[] toValueArray(BigDecimal[] bigDecimals, Session session)
throws RepositoryException {
+
+ Value[] values = new Value[bigDecimals.length];
+
+ for (int i = 0; i < bigDecimals.length; i++) {
+ values[i] = session.getValueFactory().createValue(bigDecimals[i]);
+ }
+
+ return values;
+ }
+
+ private Value[] toValueArray(Long[] longs, Session session) throws
RepositoryException {
+
+ Value[] values = new Value[longs.length];
+
+ for (int i = 0; i < longs.length; i++) {
+ values[i] = session.getValueFactory().createValue(longs[i]);
+ }
+
+ return values;
+ }
+
}
Modified:
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandler.java
URL:
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandler.java?rev=1521147&r1=1521146&r2=1521147&view=diff
==============================================================================
---
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandler.java
(original)
+++
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/ContentXmlHandler.java
Mon Sep 9 14:44:24 2013
@@ -17,6 +17,7 @@
package org.apache.sling.ide.impl.vlt.serialization;
import java.math.BigDecimal;
+import java.util.Calendar;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
@@ -52,51 +53,119 @@ public class ContentXmlHandler extends D
}
// TODO - validate that this is comprehensive
+ // TODO - does not handle correctly multi-valued properties which just one
value - do we need to?
static enum TypeHint {
BOOLEAN("Boolean") {
@Override
- Object parseValue(String rawValue) {
- return Boolean.valueOf(rawValue);
+ Object parseValues(String[] values) {
+ if (values.length == 1) {
+ return Boolean.valueOf(values[0]);
+ }
+
+ Boolean[] ret = new Boolean[values.length];
+ for (int i = 0; i < values.length; i++) {
+ ret[i] = Boolean.parseBoolean(values[i]);
+ }
+ return ret;
+
}
},
DATE("Date") {
@Override
- Object parseValue(String rawValue) {
- return ISO8601.parse(rawValue);
+ Object parseValues(String[] values) {
+
+ if (values.length == 1) {
+ return ISO8601.parse(values[0]);
+ }
+
+ Calendar[] ret = new Calendar[values.length];
+ for (int i = 0; i < values.length; i++) {
+ ret[i] = ISO8601.parse(values[i]);
+ }
+ return ret;
}
},
DOUBLE("Double") {
@Override
- Object parseValue(String rawValue) {
- return Double.parseDouble(rawValue);
+ Object parseValues(String[] values) {
+ if (values.length == 1) {
+ return Double.parseDouble(values[0]);
+ }
+
+ Double[] ret = new Double[values.length];
+ for (int i = 0; i < values.length; i++) {
+ ret[i] = Double.parseDouble(values[i]);
+ }
+ return ret;
}
},
LONG("Long") {
@Override
- Object parseValue(String rawValue) {
- return Long.valueOf(rawValue);
+ Object parseValues(String[] values) {
+ if ( values.length == 1 ) {
+ return Long.valueOf(values[0]);
+ }
+
+ Long[] ret = new Long[values.length];
+ for ( int i =0 ; i < values.length; i++ ) {
+ ret[i] = Long.valueOf(values[i]);
+ }
+ return ret;
}
},
DECIMAL("Decimal") {
@Override
- Object parseValue(String rawValue) {
- return new BigDecimal(rawValue);
+ Object parseValues(String[] values) {
+ if ( values.length == 1) {
+ return new BigDecimal(values[0]);
+ }
+
+ BigDecimal[] ret = new BigDecimal[values.length];
+ for ( int i = 0; i < values.length; i++) {
+ ret[i] = new BigDecimal(values[i]);
+ }
+ return ret;
}
};
static Object parsePossiblyTypedValue(String value) {
+ String rawValue;
+ int hintEnd = -1;
+
if (value.charAt(0) != '{') {
- return value;
+ rawValue = value;
+ } else {
+ hintEnd = value.indexOf('}');
+ rawValue = value.substring(hintEnd + 1);
+ }
+
+ String[] values;
+
+ if (rawValue.charAt(0) == '[') {
+
+ if (rawValue.charAt(rawValue.length() - 1) != ']') {
+ throw new IllegalArgumentException("Invalid multi-valued
property definition : '" + rawValue + "'");
+ }
+
+ String rawValues = rawValue.substring(1, rawValue.length() -
1);
+ values = rawValues.split(",");
+ } else {
+ values = new String[] { rawValue };
}
- int hintEnd = value.indexOf('}');
+ if (hintEnd == -1) {
+ if (values.length == 1) {
+ return values[0];
+ }
+ return values;
+ }
String rawHint = value.substring(1, hintEnd);
for (TypeHint hint : EnumSet.allOf(TypeHint.class)) {
if (hint.rawHint.equals(rawHint)) {
- return hint.parseValue(value.substring(hintEnd + 1));
+ return hint.parseValues(values);
}
}
@@ -110,7 +179,7 @@ public class ContentXmlHandler extends D
this.rawHint = rawHint;
}
- abstract Object parseValue(String rawValue);
+ abstract Object parseValues(String[] values);
}
}