Index: web/modeshape-web-jcr-rest-client/pom.xml
===================================================================
--- web/modeshape-web-jcr-rest-client/pom.xml (revision 2271)
+++ web/modeshape-web-jcr-rest-client/pom.xml (working copy)
@@ -26,6 +26,10 @@
javax.jcr
jcr
+
+ joda-time
+ joda-time
+
org.modeshape
modeshape-common
Index: web/modeshape-web-jcr-rest-client/src/main/java/org/modeshape/web/jcr/rest/client/domain/PropertyDefinition.java
===================================================================
--- web/modeshape-web-jcr-rest-client/src/main/java/org/modeshape/web/jcr/rest/client/domain/PropertyDefinition.java (revision 2271)
+++ web/modeshape-web-jcr-rest-client/src/main/java/org/modeshape/web/jcr/rest/client/domain/PropertyDefinition.java (working copy)
@@ -27,14 +27,10 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
-import java.util.Date;
import java.util.List;
import java.util.Map;
-import java.util.TimeZone;
import javax.jcr.Binary;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
@@ -42,6 +38,8 @@ import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.version.OnParentVersionAction;
import net.jcip.annotations.Immutable;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
import org.modeshape.web.jcr.rest.client.RestClientI18n;
/**
@@ -50,37 +48,9 @@ import org.modeshape.web.jcr.rest.client.RestClientI18n;
@Immutable
public class PropertyDefinition extends ItemDefinition implements javax.jcr.nodetype.PropertyDefinition {
- private static final String DATE_PATTERN1 = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
- private static final String DATE_PATTERN2 = "yyyy-MM-dd'T'HH:mm:ss.SSSz";
- private static final String DATE_PATTERN3 = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
-
- public static Calendar parseDate( String dateString ) throws ParseException {
- try {
- Date date = new SimpleDateFormat(DATE_PATTERN1).parse(dateString);
- Calendar result = Calendar.getInstance();
- result.setTime(date);
- return result;
- } catch (ParseException t) {
- try {
- // JCR allows the time zone to use ':' between hours and minutes, but this is not handled by SimpleDateFormat,
- // so remove the ':' in the time zone ...
- dateString = dateString.replaceAll("([.]\\d{1,3}[+-]?\\d{1,2})[:](\\d{1,2})$", "$1$2");
- Date date = new SimpleDateFormat(DATE_PATTERN2).parse(dateString);
- Calendar result = Calendar.getInstance();
- result.setTime(date);
- return result;
- } catch (ParseException t2) {
- try {
- Date date = new SimpleDateFormat(DATE_PATTERN3).parse(dateString);
- Calendar result = Calendar.getInstance();
- result.setTime(date);
- result.setTimeZone(TimeZone.getTimeZone("UTC"));
- return result;
- } catch (ParseException t3) {
- throw t;
- }
- }
- }
+ public static Calendar parseDate( String dateString ) throws IllegalArgumentException {
+ DateTime result = new DateTime(dateString);
+ return result.toCalendar(null);
}
private final Id id;
@@ -320,7 +290,22 @@ public class PropertyDefinition extends ItemDefinition implements javax.jcr.node
public Calendar getDate() throws ValueFormatException, RepositoryException {
try {
return parseDate(value);
- } catch (ParseException e) {
+ } catch (IllegalArgumentException e) {
+ String from = PropertyType.nameFromValue(getType());
+ String to = PropertyType.nameFromValue(PropertyType.LONG);
+ throw new ValueFormatException(RestClientI18n.unableToConvertValue.text(value, from, to), e);
+ }
+ }
+
+ public Calendar getDateInUtc() throws ValueFormatException, RepositoryException {
+ try {
+ DateTime result = new DateTime(value);
+ DateTimeZone utc = DateTimeZone.forID("UTC");
+ if (!result.getZone().equals(utc)) {
+ result = result.withZone(utc);
+ }
+ return result.toCalendar(null);
+ } catch (IllegalArgumentException e) {
String from = PropertyType.nameFromValue(getType());
String to = PropertyType.nameFromValue(PropertyType.LONG);
throw new ValueFormatException(RestClientI18n.unableToConvertValue.text(value, from, to), e);
@@ -336,7 +321,7 @@ public class PropertyDefinition extends ItemDefinition implements javax.jcr.node
public BigDecimal getDecimal() throws ValueFormatException, RepositoryException {
try {
if (getRequiredType() == PropertyType.DATE) {
- return new BigDecimal(getDate().getTime().getTime());
+ return new BigDecimal(getDateInUtc().getTime().getTime());
}
return new BigDecimal(value);
} catch (NumberFormatException t) {
@@ -355,7 +340,7 @@ public class PropertyDefinition extends ItemDefinition implements javax.jcr.node
public double getDouble() throws ValueFormatException, RepositoryException {
try {
if (getRequiredType() == PropertyType.DATE) {
- return getDate().getTime().getTime();
+ return getDateInUtc().getTime().getTime();
}
return Double.parseDouble(value);
} catch (NumberFormatException t) {
@@ -374,7 +359,7 @@ public class PropertyDefinition extends ItemDefinition implements javax.jcr.node
public long getLong() throws ValueFormatException, RepositoryException {
try {
if (getRequiredType() == PropertyType.DATE) {
- return getDate().getTime().getTime();
+ return getDateInUtc().getTime().getTime();
}
return Long.parseLong(value);
} catch (NumberFormatException t) {
Index: web/modeshape-web-jcr-rest-client/src/test/java/org/modeshape/web/jcr/rest/client/domain/PropertyDefinitionTest.java
===================================================================
--- web/modeshape-web-jcr-rest-client/src/test/java/org/modeshape/web/jcr/rest/client/domain/PropertyDefinitionTest.java (revision 2271)
+++ web/modeshape-web-jcr-rest-client/src/test/java/org/modeshape/web/jcr/rest/client/domain/PropertyDefinitionTest.java (working copy)
@@ -30,13 +30,13 @@ import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
-import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import javax.jcr.Binary;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
@@ -176,7 +176,31 @@ public class PropertyDefinitionTest {
defn = createPropertyDefinition();
assertThat(defn.getDefaultValues()[0].getString(), is("2010-03-22T01:02:03.456Z"));
assertThat(defn.getDefaultValues()[0].getDate(), is(dateFrom("2010-03-22T01:02:03.456Z")));
- assertThat(defn.getDefaultValues()[0].getLong(), is(1269237723456L));
+ assertThat(defn.getDefaultValues()[0].getLong(), is(1269219723456L));
+ }
+
+ @Test
+ public void shouldAllowConversionOfDefaultValueFromDateBeforeUtcToCompatibleTypes() throws Exception {
+ defaultValues.add("2010-03-22T01:02:03.456+08:00"); // 8 hours ahead of UTC
+ requiredType = PropertyType.DATE;
+ defn = createPropertyDefinition();
+ assertThat(defn.getDefaultValues()[0].getString(), is("2010-03-22T01:02:03.456+08:00"));
+ assertThat(defn.getDefaultValues()[0].getDate(), is(dateFrom("2010-03-22T01:02:03.456+08:00")));
+ assertThat(defn.getDefaultValues()[0].getLong(), is(1269190923456L));
+ // Verify that the supplied time in millis is 8 hours ahead of the same time in UTC millis ...
+ assertThat(TimeUnit.HOURS.convert(1269219723456L - 1269190923456L, TimeUnit.MILLISECONDS), is(8L));
+ }
+
+ @Test
+ public void shouldAllowConversionOfDefaultValueFromDateAfterUtcToCompatibleTypes() throws Exception {
+ defaultValues.add("2010-03-22T01:02:03.456-08:00"); // 8 hours after of UTC
+ requiredType = PropertyType.DATE;
+ defn = createPropertyDefinition();
+ assertThat(defn.getDefaultValues()[0].getString(), is("2010-03-22T01:02:03.456-08:00"));
+ assertThat(defn.getDefaultValues()[0].getDate(), is(dateFrom("2010-03-22T01:02:03.456-08:00")));
+ assertThat(defn.getDefaultValues()[0].getLong(), is(1269248523456L));
+ // Verify that the supplied time in millis is 8 hours behind the same time in UTC millis ...
+ assertThat(TimeUnit.HOURS.convert(1269219723456L - 1269248523456L, TimeUnit.MILLISECONDS), is(-8L));
}
@SuppressWarnings( "deprecation" )
@@ -201,25 +225,32 @@ public class PropertyDefinitionTest {
defn.getDefaultValues()[0].getBoolean();
}
- @Test( expected = ValueFormatException.class )
- public void shouldFailToConvertDefaultValueFromDoubleToDate() throws Exception {
+ @Test
+ public void shouldConvertDefaultValueFromDoubleToDate() throws Exception {
defaultValues.add("8");
requiredType = PropertyType.DOUBLE;
defn = createPropertyDefinition();
defn.getDefaultValues()[0].getDate();
}
+ @Test( expected = ValueFormatException.class )
+ public void shouldConvertDefaultValueFromNameToDate() throws Exception {
+ defaultValues.add("jcr:name");
+ requiredType = PropertyType.NAME;
+ defn = createPropertyDefinition();
+ defn.getDefaultValues()[0].getDate();
+ }
+
@Test
- public void shouldParseDate() throws ParseException {
+ public void shouldParseDate() {
PropertyDefinition.parseDate("2010-03-22T01:02:03.456-0800");
PropertyDefinition.parseDate("2010-03-22T01:02:03.456-08:00");
PropertyDefinition.parseDate("2010-03-22T01:02:03.456+0800");
PropertyDefinition.parseDate("2010-03-22T01:02:03.456+08:00");
PropertyDefinition.parseDate("2010-03-22T01:02:03.456Z");
- PropertyDefinition.parseDate("2010-03-22T01:02:03.456UTC");
}
- protected Calendar dateFrom( String dateStr ) throws ParseException {
+ protected Calendar dateFrom( String dateStr ) {
return PropertyDefinition.parseDate(dateStr);
}