Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java (revision 746932)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java (working copy)
@@ -517,7 +517,11 @@
public void setValue(Calendar value) throws RepositoryException {
if (value != null) {
- setValue(session.getValueFactory().createValue(value));
+ try {
+ setValue(session.getValueFactory().createValue(value));
+ } catch (IllegalArgumentException e) {
+ throw new ValueFormatException(e.getMessage());
+ }
} else {
remove();
}
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DateField.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DateField.java (revision 746932)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DateField.java (working copy)
@@ -74,6 +74,8 @@
/**
* Converts a millisecond time to a string suitable for indexing.
* Supported date range is: 30 BC - 3189
+ * @throws IllegalArgumentException if the given time is not
+ * within the supported date range.
*/
public static String timeToString(long time) {
@@ -81,13 +83,13 @@
if (time < 0) {
- throw new RuntimeException("time too early");
+ throw new IllegalArgumentException("time too early");
}
String s = Long.toString(time, Character.MAX_RADIX);
if (s.length() > DATE_LEN) {
- throw new RuntimeException("time too late");
+ throw new IllegalArgumentException("time too late");
}
// Pad with leading zeros
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java (revision 746932)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java (working copy)
@@ -49,6 +49,7 @@
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
+import java.util.Date;
/**
* Creates a lucene Document object from a {@link javax.jcr.Node}.
@@ -505,8 +506,13 @@
protected void addCalendarValue(Document doc, String fieldName, Object internalValue) {
Calendar value = (Calendar) internalValue;
long millis = value.getTimeInMillis();
- doc.add(createFieldWithoutNorms(fieldName, DateField.timeToString(millis),
- PropertyType.DATE));
+ try {
+ doc.add(createFieldWithoutNorms(fieldName, DateField.timeToString(millis),
+ PropertyType.DATE));
+ } catch (IllegalArgumentException e) {
+ log.warn("'{}' is outside of supported date value range.",
+ new Date(value.getTimeInMillis()));
+ }
}
/**
Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/InvalidDateTest.java
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/InvalidDateTest.java (revision 0)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/InvalidDateTest.java (revision 0)
@@ -0,0 +1,59 @@
+/*
+ * 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.util.Calendar;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Node;
+import javax.jcr.ValueFormatException;
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * InvalidDateTest contains tests for JCR-1996.
+ */
+public class InvalidDateTest extends AbstractJCRTest {
+
+ public void testDateRange() throws RepositoryException {
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.YEAR, 20000);
+ Node n = testRootNode.addNode(nodeName1);
+ try {
+ superuser.getValueFactory().createValue(cal);
+ fail("must throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ n.setProperty(propertyName1, cal);
+ fail("must throw ValueFormatException");
+ } catch (ValueFormatException e) {
+ // expected
+ }
+ String calString = superuser.getValueFactory().createValue(
+ Calendar.getInstance()).getString();
+ calString = "1" + calString;
+ try {
+ n.setProperty(propertyName1, calString, PropertyType.DATE);
+ fail("must throw ValueFormatException");
+ } catch (ValueFormatException e) {
+ // expected
+ }
+ }
+}
Property changes on: jackrabbit-core\src\test\java\org\apache\jackrabbit\core\InvalidDateTest.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java (revision 746932)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java (working copy)
@@ -39,6 +39,7 @@
suite.addTestSuite(RestoreAndCheckoutTest.class);
suite.addTestSuite(NodeImplTest.class);
suite.addTestSuite(RetentionRegistryImplTest.class);
+ suite.addTestSuite(InvalidDateTest.class);
return suite;
}
Index: jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/ISO8601.java
===================================================================
--- jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/ISO8601.java (revision 746932)
+++ jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/ISO8601.java (working copy)
@@ -211,23 +211,14 @@
* @param cal the time value to be formatted into a date/time string.
* @return the formatted date/time string.
* @throws IllegalArgumentException if a null argument is passed
+ * or the calendar cannot be represented as defined by ISO 8601 (i.e. year
+ * with more than four digits).
*/
- public static String format(Calendar cal) {
+ public static String format(Calendar cal) throws IllegalArgumentException {
if (cal == null) {
throw new IllegalArgumentException("argument can not be null");
}
- // determine era and adjust year if necessary
- int year = cal.get(Calendar.YEAR);
- if (cal.isSet(Calendar.ERA)
- && cal.get(Calendar.ERA) == GregorianCalendar.BC) {
- /**
- * calculate year using astronomical system:
- * year n BCE => astronomical year -n + 1
- */
- year = 0 - year + 1;
- }
-
/**
* the format of the date/time string is:
* YYYY-MM-DDThh:mm:ss.SSSTZD
@@ -237,7 +228,7 @@
*/
StringBuffer buf = new StringBuffer();
// year ([-]YYYY)
- buf.append(XXXX_FORMAT.format(year));
+ buf.append(XXXX_FORMAT.format(getYear(cal)));
buf.append('-');
// month (MM)
buf.append(XX_FORMAT.format(cal.get(Calendar.MONTH) + 1));
@@ -272,4 +263,32 @@
}
return buf.toString();
}
+
+ /**
+ * Returns the astonomical year of the given calendar.
+ *
+ * @param cal a calendar instance.
+ * @return the astronomical year.
+ * @throws IllegalArgumentException if calendar cannot be represented as
+ * defined by ISO 8601 (i.e. year with more
+ * than four digits).
+ */
+ public static int getYear(Calendar cal) throws IllegalArgumentException {
+ // determine era and adjust year if necessary
+ int year = cal.get(Calendar.YEAR);
+ if (cal.isSet(Calendar.ERA)
+ && cal.get(Calendar.ERA) == GregorianCalendar.BC) {
+ /**
+ * calculate year using astronomical system:
+ * year n BCE => astronomical year -n + 1
+ */
+ year = 0 - year + 1;
+ }
+
+ if (year > 9999 || year < -9999) {
+ throw new IllegalArgumentException("Calendar has more than four " +
+ "year digits, cannot be formatted as ISO8601: " + year);
+ }
+ return year;
+ }
}
Index: jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/DateValue.java
===================================================================
--- jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/DateValue.java (revision 746932)
+++ jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/DateValue.java (working copy)
@@ -37,10 +37,13 @@
* Constructs a DateValue object representing a date.
*
* @param date the date this DateValue should represent
+ * @throws IllegalArgumentException if the given date cannot be represented
+ * as defined by ISO 8601.
*/
- public DateValue(Calendar date) {
+ public DateValue(Calendar date) throws IllegalArgumentException {
super(TYPE);
this.date = date;
+ ISO8601.getYear(date);
}
/**