You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2012/11/30 18:29:08 UTC
svn commit: r1415754 [3/3] - in /sis/branches/JDK6: ./ ide-project/NetBeans/
ide-project/NetBeans/nbproject/
sis-utility/src/main/java/org/apache/sis/internal/util/
sis-utility/src/main/java/org/apache/sis/io/
sis-utility/src/main/java/org/apache/sis/m...
Copied: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java (from r1415739, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java?p2=sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java&r1=1415739&r2=1415754&rev=1415754&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java Fri Nov 30 17:29:04 2012
@@ -89,7 +89,7 @@ class KeyConstants {
names[index] = field.getName();
}
}
- } catch (ReflectiveOperationException e) {
+ } catch (Exception e) { // (ReflectiveOperationException) on JDK7
names = CharSequences.EMPTY_ARRAY;
}
keys = resize(names, length);
Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java Fri Nov 30 17:29:04 2012
@@ -41,7 +41,15 @@ public final class Messages extends Inde
* @version 0.3
* @module
*/
- public static final class Keys {
+ public static final class Keys extends KeyConstants {
+ /**
+ * The unique instance of key constants handler.
+ */
+ static final Keys INSTANCE = new Keys();
+
+ /**
+ * For {@link #INSTANCE} creation only.
+ */
private Keys() {
}
@@ -66,12 +74,11 @@ public final class Messages extends Inde
}
/**
- * Returns the {@code Keys} class.
+ * Returns the handle for the {@code Keys} constants.
*/
@Override
- final Class<?> getKeysClass() throws ClassNotFoundException {
- assert super.getKeysClass() == Keys.class;
- return Keys.class;
+ final KeyConstants getKeyConstants() {
+ return Keys.INSTANCE;
}
/**
@@ -174,9 +181,10 @@ public final class Messages extends Inde
private static final class International extends ResourceInternationalString {
private static final long serialVersionUID = -229348959712294903L;
- International(int key) {super(key);}
- International(int key, Object args) {super(key, args);}
- @Override IndexedResourceBundle getBundle(Locale locale) {
+ International(int key) {super(key);}
+ International(int key, Object args) {super(key, args);}
+ @Override KeyConstants getKeyConstants() {return Keys.INSTANCE;}
+ @Override IndexedResourceBundle getBundle(final Locale locale) {
return getResources(locale);
}
}
Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java Fri Nov 30 17:29:04 2012
@@ -17,10 +17,15 @@
package org.apache.sis.util.resources;
import java.io.Serializable;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.InvalidObjectException;
+import java.io.IOException;
import java.util.Locale;
import java.util.MissingResourceException;
import net.jcip.annotations.Immutable;
import org.apache.sis.util.Utilities;
+import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.type.AbstractInternationalString;
// Related to JDK7
@@ -45,16 +50,16 @@ abstract class ResourceInternationalStri
private static final long serialVersionUID = 4744571031462678126L;
/**
- * The key for the resource to fetch.
+ * The key for the resource to fetch. A negative value means that the resource takes no
+ * argument, in which case the {@link #arguments} field shall be ignored. Negative key
+ * values are converted to positive values using the {@code ~} operator.
*/
- private final int key;
+ private transient int key;
/**
- * The argument(s), or {@code Loader.class} if none. The choice of {@code Loader.class} for
- * meaning "no argument" is arbitrary - we just need a reference that the user is unlikely
- * to known, and we need the referenced object to be serializable. We can not use the
- * {@code null} value for "no argument" because the user may really wants to specify
- * {@code null} as an argument value.
+ * The argument(s), or {@code null} if none. Note that the user may also really want to
+ * specify {@code null} as an argument value. We distinguish the two cases with the sign
+ * of the {@link #key} value.
*/
private final Object arguments;
@@ -64,8 +69,9 @@ abstract class ResourceInternationalStri
* @param key The key for the resource to fetch.
*/
ResourceInternationalString(final int key) {
- this.key = key;
- arguments = Loader.class;
+ ArgumentChecks.ensurePositive("key", key);
+ this.key = ~key;
+ arguments = null;
}
/**
@@ -75,11 +81,21 @@ abstract class ResourceInternationalStri
* @param The argument(s).
*/
ResourceInternationalString(final int key, final Object arguments) {
+ ArgumentChecks.ensurePositive("key", key);
this.key = key;
this.arguments = arguments;
}
/**
+ * Returns a handler for the constants declared in the inner {@code Keys} class.
+ * This is used at serialization time in order to serialize the constant name
+ * rather than its numeric value.
+ *
+ * @return A handler for the constants declared in the inner {@code Keys} class.
+ */
+ abstract KeyConstants getKeyConstants();
+
+ /**
* Returns the resource bundle for the given locale.
*
* @param locale The locale for which to get the resource bundle.
@@ -104,8 +120,8 @@ abstract class ResourceInternationalStri
locale = Locale.ENGLISH;
}
final IndexedResourceBundle resources = getBundle(locale);
- return (arguments == Loader.class)
- ? resources.getString(key)
+ return (key < 0)
+ ? resources.getString(~key)
: resources.getString(key, arguments);
}
@@ -117,7 +133,7 @@ abstract class ResourceInternationalStri
*/
@Override
public boolean equals(final Object object) {
- if (object instanceof ResourceInternationalString) {
+ if (object != null && object.getClass() == getClass()) {
final ResourceInternationalString that = (ResourceInternationalString) object;
return this.key == that.key && Objects.equals(this.arguments, that.arguments);
}
@@ -131,6 +147,32 @@ abstract class ResourceInternationalStri
*/
@Override
public int hashCode() {
- return key ^ Utilities.deepHashCode(arguments) ^ (int) serialVersionUID;
+ return getClass().hashCode() ^ (key + 31*Utilities.deepHashCode(arguments)) ^ (int) serialVersionUID;
+ }
+
+ /**
+ * Serializes this international string using the key name rather than numerical value.
+ */
+ private void writeObject(final ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeUTF(getKeyConstants().getKeyName(key >= 0 ? key : ~key));
+ out.writeBoolean(key < 0);
+ }
+
+ /**
+ * Deserializes an object serialized by {@link #writeObject(ObjectOutputStream)}.
+ */
+ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ try {
+ key = getKeyConstants().getKeyValue(in.readUTF());
+ } catch (Exception cause) { // (ReflectiveOperationException) on JDK7
+ InvalidObjectException e = new InvalidObjectException(cause.toString());
+ e.initCause(cause);
+ throw e;
+ }
+ if (in.readBoolean()) {
+ key = ~key;
+ }
}
}
Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java Fri Nov 30 17:29:04 2012
@@ -41,16 +41,59 @@ public final class Vocabulary extends In
* @version 0.3
* @module
*/
- public static final class Keys {
+ public static final class Keys extends KeyConstants {
+ /**
+ * The unique instance of key constants handler.
+ */
+ static final Keys INSTANCE = new Keys();
+
+ /**
+ * For {@link #INSTANCE} creation only.
+ */
private Keys() {
}
/**
+ * Maximum value
+ */
+ public static final int MaximumValue = 5;
+
+ /**
+ * Mean value
+ */
+ public static final int MeanValue = 6;
+
+ /**
+ * Minimum value
+ */
+ public static final int MinimumValue = 4;
+
+ /**
* Name
*/
public static final int Name = 0;
/**
+ * Number of âNaNâ
+ */
+ public static final int NumberOfNaN = 3;
+
+ /**
+ * Number of values
+ */
+ public static final int NumberOfValues = 2;
+
+ /**
+ * Root Mean Square
+ */
+ public static final int RootMeanSquare = 7;
+
+ /**
+ * Standard deviation
+ */
+ public static final int StandardDeviation = 8;
+
+ /**
* Type
*/
public static final int Type = 1;
@@ -66,12 +109,11 @@ public final class Vocabulary extends In
}
/**
- * Returns the {@code Keys} class.
+ * Returns the handle for the {@code Keys} constants.
*/
@Override
- final Class<?> getKeysClass() throws ClassNotFoundException {
- assert super.getKeysClass() == Keys.class;
- return Keys.class;
+ final KeyConstants getKeyConstants() {
+ return Keys.INSTANCE;
}
/**
@@ -81,8 +123,8 @@ public final class Vocabulary extends In
* @return Resources in the given locale.
* @throws MissingResourceException if resources can't be found.
*/
- public static Messages getResources(final Locale locale) throws MissingResourceException {
- return getBundle(Messages.class, locale);
+ public static Vocabulary getResources(final Locale locale) throws MissingResourceException {
+ return getBundle(Vocabulary.class, locale);
}
/**
@@ -102,9 +144,10 @@ public final class Vocabulary extends In
private static final class International extends ResourceInternationalString {
private static final long serialVersionUID = 8360132666298806838L;
- International(int key) {super(key);}
- International(int key, Object args) {super(key, args);}
- @Override IndexedResourceBundle getBundle(Locale locale) {
+ International(int key) {super(key);}
+ International(int key, Object args) {super(key, args);}
+ @Override KeyConstants getKeyConstants() {return Keys.INSTANCE;}
+ @Override IndexedResourceBundle getBundle(final Locale locale) {
return getResources(locale);
}
}
Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties Fri Nov 30 17:29:04 2012
@@ -14,5 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-Name = Name
-Type = Type
+MaximumValue = Maximum value
+MeanValue = Mean value
+MinimumValue = Minimum value
+Name = Name
+NumberOfValues = Number of values
+NumberOfNaN = Number of \u2018NaN\u2019
+RootMeanSquare = Root Mean Square
+StandardDeviation = Standard deviation
+Type = Type
Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties Fri Nov 30 17:29:04 2012
@@ -14,5 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-Name = Nom
-Type = Type
+MaximumValue = Valeur maximale
+MeanValue = Valeur moyenne
+MinimumValue = Valeur minimale
+Name = Nom
+NumberOfValues = Nombre de valeurs
+NumberOfNaN = Nombre de \u2018NaN\u2019
+RootMeanSquare = Moyenne quadratique
+StandardDeviation = \u00c9cart type
+Type = Type
Copied: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java (from r1415739, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java?p2=sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java&r1=1415739&r2=1415754&rev=1415754&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java Fri Nov 30 17:29:04 2012
@@ -20,7 +20,6 @@ import java.util.Map;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Objects;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationHandler;
@@ -35,6 +34,9 @@ import org.apache.sis.util.LenientCompar
import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.jaxb.IdentifierMapAdapter;
+// Related to JDK7
+import org.apache.sis.internal.util.Objects;
+
/**
* The handler for an object where all methods returns null or empty collections, except
@@ -65,7 +67,7 @@ final class NilObjectHandler implements
* or modify identifiers.
*/
NilObjectHandler(final Identifier[] identifiers) {
- attribute = IdentifierMapAdapter.create(new ArrayList<>(Arrays.asList(identifiers)));
+ attribute = IdentifierMapAdapter.create(new ArrayList<Identifier>(Arrays.asList(identifiers)));
}
/**
@@ -119,21 +121,21 @@ final class NilObjectHandler implements
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
final String name = method.getName();
if (args == null) {
- switch (name) {
- case "getNilReason": {
+ /*switch (name)*/ {
+ if ("getNilReason".equals(name)) {
return (attribute instanceof NilReason) ? (NilReason) attribute : null;
}
- case "getIdentifierMap": {
+ if ("getIdentifierMap".equals(name)) {
return (attribute instanceof IdentifierMap) ? (IdentifierMap) attribute : null;
}
- case "getIdentifiers": {
+ if ("getIdentifiers".equals(name)) {
return (attribute instanceof IdentifierMapAdapter) ?
((IdentifierMapAdapter) attribute).identifiers : null;
}
- case "toString": {
+ if ("toString".equals(name)) {
return getInterface(proxy).getSimpleName() + '[' + attribute + ']';
}
- case "hashCode": {
+ if ("hashCode".equals(name)) {
return ~attribute.hashCode();
}
}
Copied: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java (from r1415739, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java?p2=sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java&r1=1415739&r2=1415754&rev=1415754&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java Fri Nov 30 17:29:04 2012
@@ -134,7 +134,7 @@ public final class NilReason implements
/**
* The pool of other nil reasons created up to date.
*/
- private static final WeakHashSet<NilReason> POOL = new WeakHashSet<>(NilReason.class);
+ private static final WeakHashSet<NilReason> POOL = new WeakHashSet<NilReason>(NilReason.class);
/**
* Either the XML value as a {@code String} (including the explanation if the prefix
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/internal/util/X364Test.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/internal/util/X364Test.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/internal/util/X364Test.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/internal/util/X364Test.java Fri Nov 30 17:29:04 2012
@@ -18,7 +18,9 @@ package org.apache.sis.internal.util;
import org.junit.Test;
import org.apache.sis.test.TestCase;
+import org.apache.sis.test.DependsOn;
+import static java.lang.String.valueOf;
import static org.junit.Assert.*;
import static org.apache.sis.internal.util.X364.*;
@@ -31,6 +33,7 @@ import static org.apache.sis.internal.ut
* @version 0.3
* @module
*/
+@DependsOn(org.apache.sis.util.CharSequencesTest.class)
public final strictfp class X364Test extends TestCase {
/**
* Tests the {@link X364#plain(String)} method.
@@ -40,13 +43,13 @@ public final strictfp class X364Test ext
String colored, plain;
colored = "Some plain text";
plain = "Some plain text";
- assertEquals(plain, plain(colored));
- assertEquals(plain.length(), lengthOfPlain(colored));
+ assertEquals(plain, valueOf(plain(colored, 0, colored.length())));
+ assertEquals(plain.length(), lengthOfPlain(colored, 0, colored.length()));
plain = "With blue in the middle";
colored = "With " + FOREGROUND_BLUE.sequence() +
"blue" + FOREGROUND_DEFAULT.sequence() + " in the middle";
- assertEquals(plain, plain(colored));
- assertEquals(plain.length(), lengthOfPlain(colored));
+ assertEquals(plain, valueOf(plain(colored, 0, colored.length())));
+ assertEquals(plain.length(), lengthOfPlain(colored, 0, colored.length()));
}
}
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java Fri Nov 30 17:29:04 2012
@@ -21,6 +21,7 @@ import java.util.Locale;
import java.util.TimeZone;
import java.util.Iterator;
import java.util.concurrent.Callable;
+import java.io.PrintWriter;
import java.lang.reflect.UndeclaredThrowableException;
import java.text.Format;
import java.text.DateFormat;
@@ -28,6 +29,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.apache.sis.util.Static;
import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.internal.util.X364;
import static org.junit.Assert.*;
@@ -42,6 +44,11 @@ import static org.junit.Assert.*;
*/
public final strictfp class TestUtilities extends Static {
/**
+ * Width of the separator to print to {@link TestCase#out}, in number of characters.
+ */
+ private static final int SEPARATOR_WIDTH = 80;
+
+ /**
* Maximal time that {@code waitFoo()} methods can wait, in milliseconds.
*
* @see #waitForBlockedState(Thread)
@@ -67,6 +74,41 @@ public final strictfp class TestUtilitie
}
/**
+ * Prints the given title to {@link TestCase#out} in a box. This method is invoked for
+ * writing a clear visual separator between the verbose output of different test cases.
+ *
+ * @param title The title to write.
+ */
+ public static void printSeparator(final String title) {
+ final PrintWriter out = TestCase.out;
+ if (out != null) {
+ final boolean isAnsiSupported = X364.isAnsiSupported();
+ if (isAnsiSupported) {
+ out.print(X364.FOREGROUND_CYAN.sequence());
+ }
+ out.print('â');
+ for (int i=0; i<SEPARATOR_WIDTH-2; i++) {
+ out.print('â');
+ }
+ out.println('â');
+ out.print("â ");
+ out.print(title);
+ for (int i=title.codePointCount(0, title.length()); i<SEPARATOR_WIDTH-3; i++) {
+ out.print(' ');
+ }
+ out.println('â');
+ out.print('â');
+ for (int i=0; i<SEPARATOR_WIDTH-2; i++) {
+ out.print('â');
+ }
+ out.println('â');
+ if (isAnsiSupported) {
+ out.print(X364.FOREGROUND_DEFAULT.sequence());
+ }
+ }
+ }
+
+ /**
* Parses the date for the given string using the {@code "yyyy-MM-dd HH:mm:ss"} pattern
* in UTC timezone.
*
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java Fri Nov 30 17:29:04 2012
@@ -47,6 +47,7 @@ import org.apache.sis.util.ArgumentCheck
import static java.lang.StrictMath.*;
import static org.opengis.test.Assert.*;
import static org.apache.sis.util.Characters.NO_BREAK_SPACE;
+import static org.apache.sis.util.CharSequences.trimWhitespaces;
// Related to JDK7
import org.apache.sis.internal.util.JDK7;
@@ -460,8 +461,8 @@ public strictfp class XMLComparator {
// For text node, continue the search if the node is empty.
case Node.TEXT_NODE: {
- final String text = node.getTextContent();
- if (text == null || text.trim().isEmpty()) {
+ final String text = trimWhitespaces(node.getTextContent());
+ if (text == null || text.isEmpty()) {
continue;
}
break;
@@ -528,7 +529,7 @@ public strictfp class XMLComparator {
* if it is actually a {@link String} object.
*/
private static Comparable<?> trim(final Comparable<?> property) {
- return (property instanceof String) ? ((String) property).trim() : property;
+ return (property instanceof String) ? trimWhitespaces(((String) property)) : property;
}
/**
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java?rev=1415754&r1=1415739&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java Fri Nov 30 17:29:04 2012
@@ -36,12 +36,12 @@ public final strictfp class Serializable
/**
* A constant for column of latitudes as floating point value.
*/
- public static final TableColumn<Float> LATITUDE = new SerializableTableColumn<>("LATITUDE", Float.class, "Latitude");
+ public static final TableColumn<Float> LATITUDE = new SerializableTableColumn<Float>("LATITUDE", Float.class, "Latitude");
/**
* A constant for column of longitudes as floating point value.
*/
- public static final TableColumn<Float> LONGITUDE = new SerializableTableColumn<>("LONGITUDE", Float.class, "Longitude");
+ public static final TableColumn<Float> LONGITUDE = new SerializableTableColumn<Float>("LONGITUDE", Float.class, "Longitude");
/**
* The programmatic name of the static final field holding this constant.
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java Fri Nov 30 17:29:04 2012
@@ -43,6 +43,7 @@ import org.junit.runners.Suite;
org.apache.sis.util.resources.IndexedResourceBundleTest.class,
org.apache.sis.util.logging.PerformanceLevelTest.class,
org.apache.sis.math.MathFunctionsTest.class,
+ org.apache.sis.math.StatisticsTest.class,
// Collections.
org.apache.sis.internal.util.ReferenceQueueConsumerTest.class,
@@ -51,6 +52,7 @@ import org.junit.runners.Suite;
org.apache.sis.util.collection.CacheTest.class,
org.apache.sis.util.collection.DerivedSetTest.class,
org.apache.sis.util.collection.DerivedMapTest.class,
+ org.apache.sis.util.collection.TableColumnTest.class,
org.apache.sis.util.collection.DefaultTreeTableTest.class,
// GeoAPI most basic types.
@@ -70,6 +72,7 @@ import org.junit.runners.Suite;
// XML most basic types.
org.apache.sis.xml.XLinkTest.class,
+ org.apache.sis.xml.NilReasonTest.class,
org.apache.sis.internal.jaxb.IdentifierMapAdapterTest.class,
org.apache.sis.internal.jaxb.IdentifierMapWithSpecialCasesTest.class
})
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java Fri Nov 30 17:29:04 2012
@@ -209,7 +209,10 @@ public final strictfp class CharSequence
*/
@Test
public void testTrimWhitespaces() {
- assertEquals("A text.", trimWhitespaces(" A text. "));
+ assertEquals("A text.", trimWhitespaces( " A text. "));
+ assertEquals("A text.", trimWhitespaces((CharSequence) " A text. "));
+ assertEquals("", trimWhitespaces( " "));
+ assertEquals("", trimWhitespaces((CharSequence) " "));
}
/**
@@ -324,7 +327,7 @@ public final strictfp class CharSequence
public void testIsUpperCase() {
assertTrue ("ABC", isUpperCase("ABC"));
assertFalse("AbC", isUpperCase("AbC"));
- assertFalse("A2C", isUpperCase("A2C")); // TODO: actually an unspecified behavior; we can change that.
+ assertFalse("A2C", isUpperCase("A2C"));
}
/**
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java Fri Nov 30 17:29:04 2012
@@ -21,7 +21,11 @@ import java.util.HashMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
+import java.io.IOException;
+import java.io.PrintWriter;
+import org.apache.sis.math.Statistics;
+import org.apache.sis.io.TableFormatter;
import org.apache.sis.util.CharSequences;
import org.apache.sis.test.TestUtilities;
import org.apache.sis.test.TestCase;
@@ -169,13 +173,19 @@ public final strictfp class CacheTest ex
/**
* Validates the entries created by the {@link #stress()} test. The check performed in
* this method shall obviously be consistent with the values created by {@code stress()}.
+ *
+ * @param cache The cache to validate.
+ * @return Statistics on the key values of the given map.
*/
- private static void validateStressEntries(final Map<Integer,Integer> cache) {
+ private static Statistics validateStressEntries(final Map<Integer,Integer> cache) {
+ final Statistics statistics = new Statistics();
for (final Map.Entry<Integer,Integer> entry : cache.entrySet()) {
final int key = entry.getKey();
final int value = entry.getValue();
assertEquals(key*key, value);
+ statistics.add(key);
}
+ return statistics;
}
/**
@@ -234,15 +244,20 @@ public final strictfp class CacheTest ex
/*
* Verifies the values.
*/
- validateStressEntries(cache);
+ final Statistics beforeGC = validateStressEntries(cache);
assertTrue("Should not have more entries than what we put in.", cache.size() <= count);
assertFalse("Some entries should be retained by strong references.", cache.isEmpty());
+ /*
+ * If verbose test output is enabled, report the number of cache hits.
+ * The numbers below are for tuning the test only. The output is somewhat
+ * random so we can not check it in a test suite. However if the test is
+ * properly tuned, most values should be non-zero.
+ */
+ final PrintWriter out = CacheTest.out;
if (out != null) {
- out.println();
- out.println("The numbers below are for tuning the test only. The output is somewhat");
- out.println("random so we can not check it in a test suite. However if the test is");
- out.println("properly tuned, most values should be non-zero.");
- out.println();
+ TestUtilities.printSeparator("CacheTest.stress() - testing concurrent accesses");
+ out.print("There is "); out.print(threads.length); out.print(" threads, each of them"
+ + " fetching or creating "); out.print(count); out.println(" values.");
out.println("Number of times a cached value has been reused, for each thread:");
for (int i=0; i<threads.length;) {
final String n = String.valueOf(threads[i++].addCount);
@@ -267,7 +282,32 @@ public final strictfp class CacheTest ex
out.println();
out.flush();
}
+ /*
+ * Gets the statistics of key values after garbage collection. The mean value should
+ * be higher, because oldest values (which should have been garbage collected first)
+ * have lower values. If verbose output is enabled, then we will print the statistics
+ * before to perform the actual check in order to allow the developer to have more
+ * information in case of failure.
+ */
System.gc();
- validateStressEntries(cache);
+ final Statistics afterGC = validateStressEntries(cache);
+ if (out != null) {
+ final TableFormatter table = new TableFormatter(out, " â ");
+ table.setMultiLinesCells(true);
+ table.append("Statistics on the keys before garbage collection:");
+ table.nextColumn();
+ table.append("Statistics on the keys after garbage collection.\n" +
+ "The minimum and the mean values should be greater.");
+ table.nextLine();
+ table.append(beforeGC.toString());
+ table.nextColumn();
+ table.append(afterGC.toString());
+ try {
+ table.flush();
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+ assertTrue("Mean key value should be greater after garbage collection.", afterGC.mean() >= beforeGC.mean());
}
}
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java Fri Nov 30 17:29:04 2012
@@ -20,10 +20,11 @@ import java.util.List;
import org.junit.Test;
import org.apache.sis.test.TestCase;
import org.apache.sis.test.TestStep;
+import org.apache.sis.test.DependsOn;
-import static org.junit.Assert.*;
+import static org.apache.sis.test.Assert.*;
import static org.apache.sis.test.TestUtilities.getSingleton;
-import static org.apache.sis.util.collection.TreeTables.*;
+import static org.apache.sis.util.collection.TableColumn.*;
/**
@@ -35,6 +36,7 @@ import static org.apache.sis.util.collec
* @version 0.3
* @module
*/
+@DependsOn(TableColumnTest.class)
public final strictfp class DefaultTreeTableTest extends TestCase {
/**
* Tests the creation of an {@link DefaultTreeTable} with initially no root node.
@@ -112,7 +114,8 @@ public final strictfp class DefaultTreeT
* Tests the displacement of nodes, in particular ensures that the parent is updated.
*
* <p>This method is part of a chain.
- * The previous method is {@link #testNodeCreation(DefaultTreeTable)}.</p>
+ * The previous method is {@link #testNodeCreation(DefaultTreeTable)} and
+ * the next method is {@link #testSerialization(TreeTable)}.</p>
*
* @param root The root node where to move children.
*/
@@ -139,12 +142,53 @@ public final strictfp class DefaultTreeT
}
/**
+ * Tests {@link DefaultTreeTable#clone()}.
+ * This will also indirectly tests {@link DefaultTreeTable#equals(Object)}.
+ *
+ * <p>This method is part of a chain.
+ * The previous method is {@link #testNodeDisplacement(TreeTable.Node)}.</p>
+ *
+ * @throws CloneNotSupportedException Should never happen.
+ */
+ @TestStep
+ private void testClone(final DefaultTreeTable table) throws CloneNotSupportedException {
+ final TreeTable newTable = table.clone();
+ assertNotSame("clone", table, newTable);
+ assertEquals("newTable.equals(table)", table, newTable);
+ assertEquals("hashCode", table.hashCode(), newTable.hashCode());
+ newTable.getRoot().getChildren().get(1).setValue(NAME, "New name");
+ assertFalse("newTable.equals(table)", newTable.equals(table));
+ }
+
+ /**
+ * Tests {@link DefaultTreeTable} serialization.
+ *
+ * <p>This method is part of a chain.
+ * The previous method is {@link #testNodeDisplacement(TreeTable.Node)}.</p>
+ */
+ @TestStep
+ private void testSerialization(final TreeTable table) {
+ final TreeTable newTable = assertSerializedEquals(table);
+ newTable.getRoot().getChildren().get(1).setValue(NAME, "New name");
+ assertFalse("newTable.equals(table)", newTable.equals(table));
+ }
+
+ /**
* Tests the creation of a tree table with a few nodes, and tests the displacement of a node
- * from one branch to another. This test is actually a chain of {@link TestStep} methods.
+ * from one branch to another. Finally tests the serialization of that table and the comparison
+ * with the original object.
+ *
+ * <p>This test is actually a chain of {@link TestStep} methods.</p>
+ *
+ * @throws CloneNotSupportedException If the {@link DefaultTreeTable#clone()} method failed.
*/
@Test
- public void testTreeTableCreation() {
- testNodeDisplacement(testNodeCreation(testTableCreation()));
+ public void testTreeTableCreation() throws CloneNotSupportedException {
+ final DefaultTreeTable table = testTableCreation();
+ final TreeTable.Node root = testNodeCreation(table);
+ testNodeDisplacement(root);
+ testClone(table);
+ testSerialization(table);
}
/**
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java Fri Nov 30 17:29:04 2012
@@ -20,9 +20,10 @@ import java.text.ParseException;
import org.junit.Test;
import org.apache.sis.test.TestCase;
import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.DependsOnMethod;
import static org.apache.sis.test.Assert.*;
-import static org.apache.sis.util.collection.ColumnConstant.*;
+import static org.apache.sis.util.collection.TableColumn.*;
/**
@@ -39,22 +40,15 @@ import static org.apache.sis.util.collec
})
public final strictfp class TreeTableFormatTest extends TestCase {
/**
- * Creates a node with a single column for object names.
- */
- private static DefaultTreeTable.Node createNode(final CharSequence name) {
- return new DefaultTreeTable.Node(NAME_MAP, new CharSequence[] {name});
- }
-
- /**
* Tests the formatting as a tree, with control on the indentation.
*/
@Test
public void testTreeFormat() {
- final DefaultTreeTable.Node root = createNode("Node #1");
- final DefaultTreeTable.Node branch = createNode("Node #2");
+ final DefaultTreeTable.Node root = new DefaultTreeTable.Node("Node #1");
+ final DefaultTreeTable.Node branch = new DefaultTreeTable.Node("Node #2");
root.getChildren().add(branch);
- root.getChildren().add(createNode("Node #3"));
- branch.getChildren().add(createNode("Node #4"));
+ root.getChildren().add(new DefaultTreeTable.Node("Node #3"));
+ branch.getChildren().add(new DefaultTreeTable.Node("Node #4"));
final TreeTableFormat tf = new TreeTableFormat(null, null);
tf.setVerticalLinePosition(2);
@@ -73,6 +67,7 @@ public final strictfp class TreeTableFor
* @throws ParseException Should never happen.
*/
@Test
+ @DependsOnMethod("testTreeFormat")
public void testTreeParse() throws ParseException {
final TreeTableFormat tf = new TreeTableFormat(null, null);
tf.setVerticalLinePosition(0);
@@ -89,36 +84,116 @@ public final strictfp class TreeTableFor
* Tests the formatting of a tree table.
*/
@Test
+ @DependsOnMethod("testTreeFormat")
public void testTreeTableFormat() {
- final StringColumn valueA = new StringColumn("value #1");
- final StringColumn valueB = new StringColumn("value #2");
+ final TableColumn<Integer> valueA = new TableColumn<Integer>(Integer.class, "value #1");
+ final TableColumn<String> valueB = new TableColumn<String> (String .class, "value #2");
final DefaultTreeTable table = new DefaultTreeTable(NAME, valueA, valueB);
final TreeTable.Node root = new DefaultTreeTable.Node(table);
- root.setValue(NAME, "Node #1");
- root.setValue(valueA, "Value #1A");
+ root.setValue(NAME, "Node #1");
+ root.setValue(valueA, 10);
root.setValue(valueB, "Value #1B");
final TreeTable.Node branch1 = new DefaultTreeTable.Node(table);
- branch1.setValue(NAME, "Node #2");
- branch1.setValue(valueA, "Value #2A");
+ branch1.setValue(NAME, "Node #2");
+ branch1.setValue(valueA, 20);
root.getChildren().add(branch1);
final TreeTable.Node branch2 = new DefaultTreeTable.Node(table);
- branch2.setValue(NAME, "Node #3");
+ branch2.setValue(NAME, "Node #3");
branch2.setValue(valueB, "Value #3B");
root.getChildren().add(branch2);
final TreeTable.Node leaf = new DefaultTreeTable.Node(table);
- leaf.setValue(NAME, "Node #4");
- leaf.setValue(valueA, "Value #4A");
- leaf.setValue(valueB, "ext #4\tafter tab\nand a new line");
+ leaf.setValue(NAME, "Node #4");
+ leaf.setValue(valueA, 40);
+ leaf.setValue(valueB, "val #4\twith tab\nand a new line");
branch1.getChildren().add(leaf);
table.setRoot(root);
final TreeTableFormat tf = new TreeTableFormat(null, null);
tf.setVerticalLinePosition(1);
- final String text = tf.format(table);
assertMultilinesEquals(
- "Node #1â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦Value #1Aâ¦â¦Value #1B\n" +
- " âââNode #2â¦â¦â¦â¦â¦â¦Value #2Aâ¦â¦\n" +
- " â   âââNode #4â¦â¦Value #4Aâ¦â¦ext #4 after tab ¶ and a new line\n" +
- " âââNode #3â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦Value #3B\n", text);
+ "Node #1â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦ 10â¦â¦ Value #1B\n" +
+ " âââNode #2â¦â¦â¦â¦â¦â¦ 20\n" +
+ " â   âââNode #4â¦â¦ 40â¦â¦ val #4 with tab ¶ and a new line\n" +
+ " âââNode #3â¦â¦â¦â¦â¦â¦ â¦â¦â¦â¦ Value #3B\n", tf.format(table));
+
+ tf.setColumns(NAME, valueA);
+ assertMultilinesEquals(
+ "Node #1â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦ 10\n" +
+ " âââNode #2â¦â¦â¦â¦â¦â¦ 20\n" +
+ " â   âââNode #4â¦â¦ 40\n" +
+ "Â âââNode #3\n", tf.format(table));
+
+ tf.setColumns(NAME, valueB);
+ assertMultilinesEquals(
+ "Node #1â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦ Value #1B\n" +
+ "Â âââNode #2\n" +
+ " â   âââNode #4â¦â¦ val #4 with tab ¶ and a new line\n" +
+ " âââNode #3â¦â¦â¦â¦â¦â¦ Value #3B\n", tf.format(table));
+ }
+
+ /**
+ * Tests the parsing of a tree table. This method parses and reformats a tree table,
+ * and performs its check on the assumption that the tree table formatting is accurate.
+ *
+ * @throws ParseException Should never happen.
+ */
+ @Test
+ @DependsOnMethod("testTreeTableFormat")
+ public void testTreeTableParse() throws ParseException {
+ final TableColumn<Integer> valueA = new TableColumn<Integer>(Integer.class, "value #1");
+ final TableColumn<String> valueB = new TableColumn<String> (String .class, "value #2");
+ final TreeTableFormat tf = new TreeTableFormat(null, null);
+ tf.setColumns(NAME, valueA, valueB);
+ tf.setVerticalLinePosition(1);
+ final String text =
+ "Node #1â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦ 10â¦â¦ Value #1B\n" +
+ " âââNode #2â¦â¦â¦â¦â¦â¦ 20\n" +
+ " â   âââNode #4â¦â¦ 40â¦â¦ Value #4B\n" +
+ " âââNode #3â¦â¦â¦â¦â¦â¦ â¦â¦â¦â¦ Value #3B\n";
+ final TreeTable table = tf.parseObject(text);
+ assertMultilinesEquals(text, tf.format(table));
+ }
+
+ /**
+ * Tests parsing and formatting using a different column separator.
+ *
+ * @throws ParseException Should never happen.
+ */
+ @Test
+ @DependsOnMethod("testTreeTableParse")
+ public void testAlternativeColumnSeparatorPattern() throws ParseException {
+ final TableColumn<Integer> valueA = new TableColumn<Integer>(Integer.class, "value #1");
+ final TableColumn<String> valueB = new TableColumn<String> (String .class, "value #2");
+ final TreeTableFormat tf = new TreeTableFormat(null, null);
+ assertEquals("?â¦â¦[â¦] ", tf.getColumnSeparatorPattern());
+ tf.setColumns(NAME, valueA, valueB);
+ tf.setVerticalLinePosition(1);
+ /*
+ * Test with all column separators.
+ */
+ tf.setColumnSeparatorPattern(" [ ]â ");
+ assertEquals(" [ ]â ", tf.getColumnSeparatorPattern());
+ final String text =
+ "Node #1 â 10 â Value #1B\n" +
+ "Â âââNode #2 â 20 â \n" +
+ " â   âââNode #4 â 40 â Value #4B\n" +
+ "Â âââNode #3 â â Value #3B\n";
+ final TreeTable table = tf.parseObject(text);
+ assertMultilinesEquals(text, tf.format(table));
+ /*
+ * Test with omission of column separator for trailing null values.
+ */
+ tf.setColumnSeparatorPattern("? [ ]; ");
+ assertMultilinesEquals(
+ "Node #1 ; 10 ; Value #1B\n" +
+ "Â âââNode #2 ; 20\n" + // Column separator omitted here.
+ " â   âââNode #4 ; 40 ; Value #4B\n" +
+ "Â âââNode #3 ; ; Value #3B\n", tf.format(table));
+ /*
+ * Test with regular expression at parsing time.
+ */
+ tf.setColumnSeparatorPattern("?â¦â¦[â¦] /\\w*â+\\w*");
+ assertEquals("?â¦â¦[â¦] /\\w*â+\\w*", tf.getColumnSeparatorPattern());
+ assertEquals(table, tf.parseObject(text));
}
}
Modified: sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java (original)
+++ sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java Fri Nov 30 17:29:04 2012
@@ -30,7 +30,7 @@ import org.apache.sis.test.TestCase;
import org.junit.Test;
import org.junit.After;
-import static org.junit.Assert.*;
+import static org.apache.sis.test.Assert.*;
/**
@@ -155,10 +155,12 @@ public final strictfp class IndexedResou
InternationalString i18n = Errors.formatInternational(Errors.Keys.NullArgument_1);
assertEquals("Argument â{0}â shall not be null.", i18n.toString(Locale.ENGLISH));
assertEquals("Lâargument â{0}â ne doit pas être nul.", i18n.toString(Locale.FRENCH));
+ assertNotSame(i18n, assertSerializedEquals(i18n));
i18n = Errors.formatInternational(Errors.Keys.NullArgument_1, "CRS");
assertEquals("Argument âCRSâ shall not be null.", i18n.toString(Locale.ENGLISH));
assertEquals("Lâargument âCRSâ ne doit pas être nul.", i18n.toString(Locale.FRENCH));
+ assertNotSame(i18n, assertSerializedEquals(i18n));
}
/**
Modified: sis/branches/JDK6/src/main/docbook/book.xsl
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/src/main/docbook/book.xsl?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/src/main/docbook/book.xsl (original)
+++ sis/branches/JDK6/src/main/docbook/book.xsl Fri Nov 30 17:29:04 2012
@@ -95,6 +95,9 @@
<xsl:template match= "d:function[@role = 'OGC']" mode="class.value"> <xsl:value-of select="'OGC'" /> </xsl:template>
<xsl:template match= "d:function[@role = 'GeoAPI']" mode="class.value"> <xsl:value-of select="'GeoAPI'"/> </xsl:template>
<xsl:template match= "d:function[@role = 'SIS']" mode="class.value"> <xsl:value-of select="'SIS'" /> </xsl:template>
+ <xsl:template match= "d:constant[@role = 'OGC']" mode="class.value"> <xsl:value-of select="'OGC'" /> </xsl:template>
+ <xsl:template match= "d:constant[@role = 'GeoAPI']" mode="class.value"> <xsl:value-of select="'GeoAPI'"/> </xsl:template>
+ <xsl:template match= "d:constant[@role = 'SIS']" mode="class.value"> <xsl:value-of select="'SIS'" /> </xsl:template>
<xsl:template match= "d:literal[@role = 'OGC']" mode="class.value"> <xsl:value-of select="'OGC'" /> </xsl:template>
<xsl:template match= "d:literal[@role = 'GeoAPI']" mode="class.value"> <xsl:value-of select="'GeoAPI'"/> </xsl:template>
<xsl:template match= "d:literal[@role = 'SIS']" mode="class.value"> <xsl:value-of select="'SIS'" /> </xsl:template>
Modified: sis/branches/JDK6/src/main/docbook/fr/XML.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/src/main/docbook/fr/XML.xml?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/src/main/docbook/fr/XML.xml (original)
+++ sis/branches/JDK6/src/main/docbook/fr/XML.xml Fri Nov 30 17:29:04 2012
@@ -226,5 +226,63 @@ public class MyClass {
où peuvent être manipulés tous types dâidentifiants (pas seulement <acronym>XML</acronym>) associés à un objet.
</para>
</section>
+
+ <section>
+ <title>Représentation de valeurs manquantes</title>
+ <para>
+ Lorsquâun attribut nâest pas défini, la méthode correspondante de GeoAPI retourne généralement <literal>null</literal>.
+ Toutefois les choses se compliquent lorsque lâattribut manquant est une valeur considérée comme obligatoire par le standard <acronym>ISO</acronym> 19115.
+ Le standard <acronym>ISO</acronym> 19139 autorise lâomission dâattributs obligatoires à la condition dâindiquer pourquoi la valeur est manquante.
+ Les raisons peuvent être que lâattribut ne sâapplique pas (<constant role="OGC">inapplicable</constant>),
+ que la valeur existe probablement mais nâest pas connue (<constant role="OGC">unknown</constant>),
+ que la valeur pourrait ne pas exister (<constant role="OGC">missing</constant>),
+ quâelle ne peut pas être divulguée (<constant role="OGC">withheld</constant>), <foreignphrase>etc.</foreignphrase>
+ La transmission de cette information nécessite lâutilisation dâun objet non-nul même lorsque la valeur est manquante.
+ <acronym>SIS</acronym> procède en retournant un objet qui, en plus dâimplémenter lâinterface GeoAPI attendue,
+ implémente aussi lâinterface <classname role="SIS">org.apache.xml.NilObject</classname>.
+ Cette interface marque les instances dont toutes les méthodes retournent une collection vide,
+ un tableau vide, <literal>null</literal>, <literal>NaN</literal>, <literal>0</literal> ou <literal>false</literal>,
+ dans cet ordre de préférence selon ce que les types de retours des méthodes permettent.
+ Chaque instance implémentant <classname role="SIS">NilObject</classname> fournit une méthode
+ <classname role="SIS">getNilReason()</classname> indiquant pourquoi lâobjet est nul.
+ </para>
+ <para>
+ Dans lâexemple suivant, la partie gauche montre un élément <classname role="OGC">CI_Citation</classname>
+ contenant un élément <classname role="OGC">CI_Series</classname>, alors que dans la partie droite la série est inconnue.
+ Si lâélément <classname role="OGC">CI_Series</classname> avait été complètement omis,
+ alors la méthode <function role="GeoAPI">Citation.getSeries()</function> retournerait <literal>null</literal> en Java.
+ Mais en présence dâun attribut <literal role="OGC">nilReason</literal>, lâimplémentation <acronym>SIS</acronym>
+ de <function role="SIS">getSeries()</function> retournera plutôt un objet implémentant à la fois les interfaces
+ <classname role="GeoAPI">Series</classname> et <classname role="SIS">NilReason</classname>,
+ et dont la méthode <function role="SIS">getNilReason()</function> retournera la constante <constant role="SIS">UNKNOWN</constant>.
+ </para>
+ <example>
+ <title>Ãlément obligatoire marqué comme inconnu dans une méta-donnée</title>
+ <informaltable frame="none">
+ <tgroup cols="2">
+ <colspec colwidth="50%"/>
+ <colspec colwidth="50%"/>
+ <tbody>
+ <row>
+ <entry>
+ <programlisting language="xml"><gmd:CI_Citation>
+ <gmd:series>
+ <gmd:CI_Series>
+ <!-- Some content here -->
+ </gmd:CI_Series>
+ </gmd:series>
+</gmd:CI_Citation></programlisting>
+ </entry>
+ <entry>
+ <programlisting language="xml"><gmd:CI_Citation>
+ <gmd:series nilReason="unknown"/>
+</gmd:CI_Citation></programlisting>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </example>
+ </section>
</section>
</chapter>
Modified: sis/branches/JDK6/src/main/docbook/fr/utility.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/src/main/docbook/fr/utility.xml?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/src/main/docbook/fr/utility.xml (original)
+++ sis/branches/JDK6/src/main/docbook/fr/utility.xml Fri Nov 30 17:29:04 2012
@@ -13,6 +13,72 @@
</para>
<section>
+ <title>Modes de comparaisons des objets</title>
+ <para>
+ Il existe différentes opinions sur la façon dâimplémenter la méthode <function>Object.equals(Object)</function> du Java standard.
+ Selon certains, il doit être possible de comparer différentes implémentations dâune même interface ou classe de base.
+ Mais cette politique nécessite que chaque interface ou classe de base définisse entièrement dans sa Javadoc les critères ou calculs
+ que doivent employer les méthodes <function>equals(Object)</function> et <function>hashCode()</function> dans toutes les implémentations.
+ Cette approche est choisie notamment par <classname>java.util.Collection</classname> et ses interfaces filles.
+ Elle se fait toutefois au détriment de la possibilité de prendre en compte des attributs supplémentaires dans les interfaces filles,
+ si cette possibilité nâa pas été spécifiée dans lâinterface parente.
+ Cette contrainte découle des points suivants du contrat des méthodes <function>equals(Object)</function> et <function>hashCode()</function>:
+ </para>
+ <itemizedlist>
+ <listitem><literal>A.equals(B)</literal> implique <literal>B.equals(A)</literal> (symétrie);</listitem>
+ <listitem><literal>A.equals(B)</literal> et <literal>B.equals(C)</literal> implique <literal>A.equals(C)</literal> (transitivité);</listitem>
+ <listitem><literal>A.equals(B)</literal> implique <literal>A.hashCode() == B.hashCode()</literal>.</listitem>
+ </itemizedlist>
+ <para>
+ Par exemple ces trois contraintes sont violées si <varname>A</varname> (et éventuellement <varname>C</varname>)
+ peuvent contenir des attributs que <varname>B</varname> ignore.
+ Pour contourner cette difficulté, une approche alternative consiste à exiger que les objets comparés par la méthode
+ <function>Object.equals(Object)</function> soient exactement de la même classe, câest-à -dire que <literal>A.getClass() == B.getClass()</literal>.
+ Cette approche est parfois considérée contraire aux principes de la programmation orientée objets.
+ Dans la pratique, pour des applications relativement complexes, ça dépend du contexte dans lequel les objets sont comparés:
+ si les objets sont ajoutés à un <classname>HashSet</classname> ou utilisés comme clés dans un <classname>HashMap</classname>,
+ alors nous avons besoin dâun strict respect du contrat de <function>equals(Object)</function> et <function>hashCode()</function>.
+ Mais si le développeur compare les objets lui-même, par exemple pour vérifier si des informations qui lâintéresse ont changées,
+ alors les contraintes de symétrie, transitivité ou de cohérence avec les valeurs de hachages peuvent ne pas être pertinentes pour lui.
+ Des comparaisons plus permissives peuvent être souhaitables, allant parfois jusquâà tolérer de légers écarts dans les valeurs numériques.
+ </para>
+ <para>
+ Afin de donner une certaine flexibilité aux développeurs, un grand nombre de classes de la bibliothèque <acronym>SIS</acronym>
+ implémentent lâinterface <classname role="SIS">org.apache.sis.util.LenientComparable</classname>, qui défini une méthode <function role="SIS">equals(Object, ComparisonMode)</function>.
+ Les principaux modes de comparaisons sont:
+ </para>
+ <itemizedlist>
+ <listitem><para>
+ <emphasis role="bold"><constant role="SIS">STRICT</constant></emphasis> â Les objets comparés doivent être de la même classe
+ et tous leurs attributs strictement égaux, y compris dâéventuels attributs publics propres à lâimplémentation.
+ </para></listitem>
+ <listitem><para>
+ <emphasis role="bold"><constant role="SIS">BY_CONTRACT</constant></emphasis> â Les objets comparés doivent implémenter la même interface de GeoAPI (ou tout autre standard),
+ mais nâont pas besoin dâêtre de la même classe dâimplémentation. Seuls les attributs définis dans lâinterface sont comparés;
+ tout autres attributs propres à lâimplémentation â même sâils sont publics â sont ignorés.
+ </para></listitem>
+ <listitem><para>
+ <emphasis role="bold"><constant role="SIS">IGNORE_METADATA</constant></emphasis>Â â Comme <constant role="SIS">BY_CONTRACT</constant>,
+ mais ne compare que les attributs qui influencent les opérations (calculs numériques ou autre) effectuées par lâobjet.
+ Par exemple dans un référentiel géodésique, la longitude (par rapport à Greenwich) du méridien dâorigine sera pris en compte
+ alors que le nom de ce méridien sera ignoré.
+ </para></listitem>
+ <listitem><para>
+ <emphasis role="bold"><constant role="SIS">APPROXIMATIVE</constant></emphasis>Â â Comme <constant role="SIS">IGNORE_METADATA</constant>,
+ mais tolère de légères différences dans les valeurs numériques.
+ </para></listitem>
+ </itemizedlist>
+ <para>
+ Le mode par défaut, utilisé par les toutes les méthodes <function>equals(Object)</function> de <acronym>SIS</acronym>,
+ est <constant role="SIS">STRICT</constant>. Ce mode est choisi à la fois pour une utilisation plus sécuritaire avec <classname>HashMap</classname>,
+ et aussi parce que définir rigoureusement le contrat des méthodes <function>equals(Object)</function> et <function>hashCode()</function>
+ dans les centaines dâinterfaces de GeoAPI semble une entreprise peu réaliste, qui risque dâêtre assez peu suivit par les diverses implémentations.
+ </para>
+ </section>
+
+
+
+ <section>
<title>Internationalisation</title>
<para>
Dans une architecture où un programme exécuté sur un serveur fournit ses données à plusieurs clients,
@@ -26,7 +92,7 @@
</para>
<section>
- <title>Instances distinctes pour chaque conventions locales</title>
+ <title>Chaînes de caractères distinctes pour chaque conventions locales</title>
<para>
Certaines classes ne sont conçues que pour fonctionner selon une convention locale à la fois.
Câest évidemment le cas des implémentations standards de <classname>java.text.Format</classname>,
@@ -34,7 +100,7 @@
Mais câest aussi le cas de dâautres classes moins évidentes comme
<classname>javax.imageio.ImageReader</classname>/<classname>ImageWriter</classname> ainsi que les exceptions.
Lorsque une de ces classes est implémentée par <acronym>SIS</acronym>,
- nous lâidentifions en implémentant lâinterface <classname role="SIS">Localized</classname>.
+ nous lâidentifions en implémentant lâinterface <classname role="SIS">org.apache.sis.util.Localized</classname>.
La méthode <function role="SIS">getLocale()</function> de cette interface permet alors de déterminer
selon quelles conventions locales lâinstance produira ses messages.
</para>
@@ -99,5 +165,95 @@
pour des raisons dâéconomie de mémoire.
</para>
</section>
+
+ <section>
+ <title>Traitement des caractères</title>
+ <para>
+ Les chaînes de caractères en Java utilisent lâencodage UTF-16. Il existe une correspondance directe
+ entre les valeurs de type <classname>char</classname> et la très grande majorité des caractères, ce
+ qui facilite lâutilisation des chaînes lorsque ces caractères suffisent.
+ Mais certains caractères Unicode ne sont pas représentables par un seul <classname>char</classname>.
+ Ces <firstterm>caractères supplémentaires</firstterm> comprennent certains idéogrammes,
+ mais aussi des symboles routiers et géographiques dans la plage 1F680 à 1F700.
+ Le support de ces caractères supplémentaires nécessite des itérations un peu plus complexes
+ que le cas classique où lâon supposait une correspondance directe.
+ Ainsi, au lieu de la boucle de gauche ci-dessous, les applications internationales devraient
+ généralement utiliser la boucle de droite:
+ </para>
+ <example>
+ <title>Boucle sur une chaîne pouvant contenir des caractères supplémentaires</title>
+ <informaltable frame="none">
+ <tgroup cols="2">
+ <colspec colwidth="50%"/>
+ <colspec colwidth="50%"/>
+ <tbody>
+ <row>
+ <entry>
+ <programlisting language="java">for (int i=0; i<string.length(); i++) {
+ char c = string.charAt(i);
+ if (Character.isWhitespace(c)) {
+ // Un espace blanc a été trouvé.
+ }
+}</programlisting>
+ </entry>
+ <entry>
+ <programlisting language="java">for (int i=0; i<string.length();) {
+ int c = string.codePointAt(i);
+ if (Character.isWhitespace(c)) {
+ // Un espace blanc a été trouvé.
+ }
+ i += Character.charCount(c);
+}</programlisting>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </example>
+ <para>
+ <acronym>SIS</acronym> supporte les caractères supplémentaires en utilisant la boucle de droite lorsque nécessaire.
+ Mais la boucle de gauche reste occasionnellement utilisée lorsquâil est connu que les caractères recherchés ne sont
+ pas des caractères supplémentaires, même si la chaîne dans laquelle on fait la recherche peut en contenir.
+ </para>
+
+ <section>
+ <title>Interprétation des espaces blancs</title>
+ <para>
+ Le Java standard fournit deux méthodes pour déterminer si un caractères est un espace blanc:
+ <function>Character.isWhitespace(â¦)</function> et <function>Character.isSpaceChar(â¦)</function>.
+ Ces deux méthodes diffèrent dans leurs interprétations des espaces insécables, des tabulations et des retours à la ligne.
+ La première méthode est conforme à lâinterprétation couramment utilisée dans des langages telles que le Java, C/C++ et XML,
+ qui considère les tabulations et retours à la ligne comme des espaces blancs,
+ alors que les espaces insécables sont interprétés comme des caractères non-blanc.
+ La seconde méthode â strictement conforme à la définition Unicode â fait lâinterprétation inverse.
+ </para>
+ <para>
+ <acronym>SIS</acronym> emploie ces deux méthodes dans des contextes différents.
+ <function>isWhitespace(â¦)</function> est utilisée pour <emphasis>séparer</emphasis>
+ les éléments dâune liste (nombres, dates, mots, <foreignphrase>etc.</foreignphrase>),
+ tandis que <function>isSpaceChar(â¦)</function> est utilisée pour ignorer les espaces
+ blancs <emphasis>à lâintérieur</emphasis> dâun seul élément.
+ </para>
+ <informalexample><para>
+ <emphasis role="bold">Exemple:</emphasis>
+ Supposons une liste de nombres représentés selon les conventions françaises.
+ Chaque nombre peut contenir des <emphasis>espace insécables</emphasis> comme séparateurs des milliers,
+ tandis que les différents nombres de la liste peuvent être séparés par des espaces ordinaires, des tabulations ou des retours à la ligne.
+ Pendant lâanalyse dâun nombre, on veut considérer les espaces insécables comme faisant partie du nombre,
+ alors quâune tabulation ou un retour à la ligne indique très probablement une séparation entre ce nombre et le nombre suivant.
+ On utilisera donc <function>isSpaceChar(â¦)</function>.
+ Inversement, lors de la séparation des nombres de la liste, on veut considérer les tabulations et
+ les retours à la ligne comme des séparateurs mais pas les espaces insécables.
+ On utilisera donc <function>isWhitespace(â¦)</function>.
+ Le rôle des espaces ordinaires, qui pourraient sâappliquer aux deux cas, doit être décidé en amont.
+ </para></informalexample>
+ <para>
+ Dans la pratique, cette distinction se traduit pas une utilisation de <function>isSpaceChar(â¦)</function>
+ dans les implémentations de <classname>java.text.Format</classname>,
+ et une utilisation de <function>isWhitespace(â¦)</function> dans pratiquement tout le reste
+ de la bibliothèque <acronym>SIS</acronym>.
+ </para>
+ </section>
+ </section>
</section>
</chapter>
Modified: sis/branches/JDK6/src/site/resources/book/book.css
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/src/site/resources/book/book.css?rev=1415754&r1=1415753&r2=1415754&view=diff
==============================================================================
--- sis/branches/JDK6/src/site/resources/book/book.css (original)
+++ sis/branches/JDK6/src/site/resources/book/book.css Fri Nov 30 17:29:04 2012
@@ -54,10 +54,18 @@ p {
*/
pre.programlisting {
border-style: solid;
+ border-color: gray;
border-width: 1pt;
padding: 9pt;
}
+/* If inside a table, rely on the table border instead. */
+table pre.programlisting {
+ border-style: none;
+ margin: 0pt;
+ padding: 0pt;
+}
+
div.sidebar {
margin-left: 1.25cm;
margin-right: 1.5cm;
@@ -79,11 +87,22 @@ div.informalexample {
/*
* Tables.
*/
+div.informaltable table tr {
+ vertical-align: top;
+}
+
+div.informaltable table tr td {
+ border-style: solid;
+ border-color: gray;
+ border-width: 1pt;
+ padding: 9pt;
+}
+
div.table p.title {
text-align: center;
}
-table {
+div.table-contents table {
margin-left: auto;
margin-right: auto;
border-style: solid;
@@ -91,25 +110,25 @@ table {
border-spacing: 0pt;
}
-table tr th {
+div.table-contents table tr th {
background-color: #B9DCFF;
border-bottom-style: solid;
border-bottom-width: 1pt;
padding: 3pt;
}
-table tr td {
+div.table-contents table tr td {
padding-left: 9pt;
padding-right: 9pt;
}
-table tr td.leftBorder {
+div.table-contents table tr td.leftBorder {
border-left-style: solid;
border-left-width: 1pt;
border-left-color: lightgray;
}
-table tr td.separator {
+div.table-contents table tr td.separator {
text-align: center;
font-weight: bold;
background-color: #EEEEFF;