Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java Fri Feb 1 19:34:39 2013 @@ -59,7 +59,8 @@ public interface IdentifierSpace<T> exte * Its type is {@code "xs:ID"} - i.e. it is a fragment identifier, unique within document scope only, * for internal cross-references. It is not useful by itself as a persistent unique identifier. * - * <p>The XML {@linkplain #getName() attribute name} is {@code "gml:id"}.</p> + * <p>The XML {@linkplain #getName() attribute name} is {@code "gml:id"}. + * The XML attribute name of the reference to an identified object is {@code "xlink:href"}.</p> * * @see javax.xml.bind.annotation.XmlID */ @@ -70,7 +71,8 @@ public interface IdentifierSpace<T> exte * that implement ISO 19115 in XML. May be used as a persistent unique identifier, but only * available within GMD context. * - * <p>The XML {@linkplain #getName() attribute name} is {@code "gco:uuid"}.</p> + * <p>The XML {@linkplain #getName() attribute name} is {@code "gco:uuid"}. + * The XML attribute name of the reference to an identified object is {@code "gco:uuidref"}.</p> * * @see UUID */
Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java Fri Feb 1 19:34:39 2013 @@ -18,14 +18,17 @@ package org.apache.sis.xml; import java.util.Map; import java.util.Deque; -import java.util.LinkedList; import java.util.Collections; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.atomic.AtomicBoolean; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import net.jcip.annotations.ThreadSafe; import org.apache.sis.util.logging.Logging; +import org.apache.sis.internal.util.DelayedExecutor; +import org.apache.sis.internal.util.DelayedRunnable; import org.apache.sis.internal.jaxb.AdapterReplacement; @@ -51,15 +54,15 @@ import org.apache.sis.internal.jaxb.Adap * @module * * @see XML - * - * @todo Need a timeout for disposing marshallers that have been unused for a while. */ @ThreadSafe public class MarshallerPool { /** - * Maximal amount of marshallers and unmarshallers to keep. + * Amount of nanoseconds to wait before to remove unused (un)marshallers. + * This is a very approximative value: actual timeout will not be shorter, + * but may be twice longer. */ - private static final int CAPACITY = 16; + private static final long TIMEOUT = 15000000000L; // 15 seconds. /** * The key to be used in the map given to the constructors for specifying the root namespace. @@ -85,16 +88,38 @@ public class MarshallerPool { private final Object mapper; /** - * The pool of marshaller. This pool is initially empty - * and will be filled with elements as needed. + * The pool of marshaller. This pool is initially empty and will be filled with elements as needed. + * Marshallers (if any) shall be fetched using the {@link Deque#poll()} method and, after use, + * given back to the pool using the {@link Deque#push(Object)} method. + * + * <p>This queue must be a thread-safe implementation, since it will not be invoked in + * synchronized block.</p> + * + * @see #acquireMarshaller() + * @see #release(Marshaller) + */ + private final Deque<Marshaller> marshallers; + + /** + * The pool of unmarshaller. This pool is initially empty and will be filled with elements as needed. + * Unmarshallers (if any) shall be fetched using the {@link Deque#poll()} method and, after use, + * given back to the pool using the {@link Deque#push(Object)} method. + * + * <p>This queue must be a thread-safe implementation, since it will not be invoked in + * synchronized block.</p> + * + * @see #acquireUnmarshaller() + * @see #release(Unmarshaller) */ - private final Deque<Marshaller> marshallers = new LinkedList<Marshaller>(); + private final Deque<Unmarshaller> unmarshallers; /** - * The pool of unmarshaller. This pool is initially empty - * and will be filled with elements as needed. + * {@code true} if a task has been scheduled for removing expired (un)marshallers, + * or {@code false} if no removal task is currently scheduled. + * + * @see #scheduleRemoval() */ - private final Deque<Unmarshaller> unmarshallers = new LinkedList<Unmarshaller>(); + private final AtomicBoolean isRemovalScheduled; /** * Creates a new factory for the given class to be bound, with a default empty namespace. @@ -120,11 +145,14 @@ public class MarshallerPool { /** * Creates a new factory for the given packages, with a default empty namespace. - * The separator character for the packages is the colon. + * The separator character for the packages is the colon. Example: * - * @param packages The packages in which JAXB will search for annotated classes to be bound, - * for example {@code "org.apache.sis.metadata.iso:org.apache.sis.metadata.iso.citation"}. - * @throws JAXBException If the JAXB context can not be created. + * {@preformat text + * "org.apache.sis.metadata.iso:org.apache.sis.metadata.iso.citation" + * } + * + * @param packages The colon-separated list of packages in which JAXB will search for annotated classes. + * @throws JAXBException If the JAXB context can not be created. */ public MarshallerPool(final String packages) throws JAXBException { this(Collections.<String,String>emptyMap(), packages); @@ -136,8 +164,7 @@ public class MarshallerPool { * in this class like {@link #ROOT_NAMESPACE_KEY}. * * @param properties The set of properties to be given to the pool. - * @param packages The packages in which JAXB will search for annotated classes to be bound, - * for example {@code "org.apache.sis.metadata.iso:org.apache.sis.metadata.iso.citation"}. + * @param packages The colon-separated list of packages in which JAXB will search for annotated classes. * @throws JAXBException If the JAXB context can not be created. */ public MarshallerPool(final Map<String,String> properties, final String packages) throws JAXBException { @@ -173,50 +200,112 @@ public class MarshallerPool { } /* * Instantiates the OGCNamespacePrefixMapper appropriate for the implementation - * we just detected. + * we just detected. Note that we may get NoClassDefFoundError instead than the + * usual ClassNotFoundException if the class was found but its parent class has + * not been found. */ try { mapper = Class.forName(type).getConstructor(String.class).newInstance(rootNamespace); } catch (Throwable exception) { // (ReflectiveOperationException | NoClassDefFoundError) on JDK7 branch. - // The NoClassDefFoundError is because of our trick using "geotk-provided". throw new JAXBException("Unsupported JAXB implementation.", exception); } - } - - /** - * Returns the marshaller or unmarshaller to use from the given queue. - * If the queue is empty, returns {@code null}. - */ - private static <T> T acquire(final Deque<T> queue) { - synchronized (queue) { - return queue.pollLast(); - } + marshallers = new LinkedBlockingDeque<Marshaller>(); + unmarshallers = new LinkedBlockingDeque<Unmarshaller>(); + isRemovalScheduled = new AtomicBoolean(); } /** * Marks the given marshaller or unmarshaller available for further reuse. + * This method: + * + * <ul> + * <li>{@link Pooled#reset() Resets} the (un)marshaller to its initial state.</li> + * <li>{@linkplain Deque#push(Object) Pushes} the (un)marshaller in the given queue.</li> + * <li>Registers a delayed task for disposing expired (un)marshallers after the timeout.</li> + * </ul> */ - private static <T> void release(final Deque<T> queue, final T marshaller) { + private <T> void release(final Deque<T> queue, final T marshaller) { try { ((Pooled) marshaller).reset(); } catch (JAXBException exception) { - // Not expected to happen because the we are supposed + // Not expected to happen because we are supposed // to reset the properties to their initial values. Logging.unexpectedException(MarshallerPool.class, "release", exception); return; } - synchronized (queue) { - queue.addLast(marshaller); - while (queue.size() > CAPACITY) { - // Remove the least recently used marshallers. - queue.removeFirst(); + queue.push(marshaller); + scheduleRemoval(); + } + + /** + * Schedule a new task for removing expired (un)marshallers if no such task is currently + * registered. If a task is already registered, then this method does nothing. Note that + * this task will actually wait for a longer time than the {@link #TIMEOUT} value before + * to execute, in order to increase the chances to process many (un)marshallers at once. + */ + private void scheduleRemoval() { + if (isRemovalScheduled.compareAndSet(false, true)) { + DelayedExecutor.schedule(new DelayedRunnable(System.nanoTime() + 2*TIMEOUT) { + @Override public void run() { + removeExpired(); + } + }); + } + } + + /** + * Invoked from the task scheduled by {@link #scheduleRemoval()} for removing expired + * (un)marshallers. If some (un)marshallers remain after execution of this task, then + * this method will reschedule a new task for checking again later. + */ + final void removeExpired() { + isRemovalScheduled.set(false); + final long now = System.nanoTime(); + if (!removeExpired(marshallers, now) | // Really |, not || + !removeExpired(unmarshallers, now)) + { + scheduleRemoval(); + } + } + + /** + * Removes expired (un)marshallers from the given queue. + * + * @param <T> Either {@code Marshaller} or {@code Unmarshaller} type. + * @param queue The queue from which to remove expired (un)marshallers. + * @param now Current value of {@link System#nanoTime()}. + * @return {@code true} if the queue became empty as a result of this method call. + */ + private static <T> boolean removeExpired(final Deque<T> queue, final long now) { + T next; + while ((next = queue.peekLast()) != null) { + /* + * The above line fetched the oldest (un)marshaller without removing it. + * If the timeout is not yet elapsed, do not remove that (un)marshaller. + * Since marshallers are enqueued in chronological order, the next ones + * should be yet more recent, so it is not worth to continue the search. + */ + if (now - ((Pooled) next).resetTime < TIMEOUT) { + return false; + } + /* + * Now remove the (un)marshaller and check again the timeout. This second + * check is because the oldest (un)marshaller may have changed concurrently + * (depending on the queue implementation, which depends on the target JDK). + * If such case, restore the (un)marshaller on the queue. + */ + next = queue.pollLast(); + if (now - ((Pooled) next).resetTime < TIMEOUT) { + queue.addLast(next); + return false; } } + return true; } /** * Returns a JAXB marshaller from the pool. If there is no marshaller currently available - * in the pool, then this method will {@linkplain #createMarshaller create} a new one. + * in the pool, then this method will {@linkplain #createMarshaller() create} a new one. * * <p>This method shall be used as below:</p> * @@ -234,7 +323,7 @@ public class MarshallerPool { * @throws JAXBException If an error occurred while creating and configuring a marshaller. */ public Marshaller acquireMarshaller() throws JAXBException { - Marshaller marshaller = acquire(marshallers); + Marshaller marshaller = marshallers.poll(); if (marshaller == null) { marshaller = new PooledMarshaller(createMarshaller(), internal); } @@ -243,7 +332,7 @@ public class MarshallerPool { /** * Returns a JAXB unmarshaller from the pool. If there is no unmarshaller currently available - * in the pool, then this method will {@linkplain #createUnmarshaller create} a new one. + * in the pool, then this method will {@linkplain #createUnmarshaller() create} a new one. * * <p>This method shall be used as below:</p> * @@ -261,7 +350,7 @@ public class MarshallerPool { * @throws JAXBException If an error occurred while creating and configuring the unmarshaller. */ public Unmarshaller acquireUnmarshaller() throws JAXBException { - Unmarshaller unmarshaller = acquire(unmarshallers); + Unmarshaller unmarshaller = unmarshallers.poll(); if (unmarshaller == null) { unmarshaller = new PooledUnmarshaller(createUnmarshaller(), internal); } Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java Fri Feb 1 19:34:39 2013 @@ -29,6 +29,7 @@ import org.apache.sis.util.ArgumentCheck * * @author Cédric Briançon (Geomatys) * @author Quentin Boileau (Geomatys) + * @author Guilhem Legal (Geomatys) * @since 0.3 (derived from geotk-3.00) * @version 0.3 * @module @@ -73,6 +74,13 @@ public final class Namespaces extends St * * @category ISO */ + public static final String GTS = "http://www.isotc211.org/2005/gts"; + + /** + * The <code>{@value}</code> URL. + * + * @category ISO + */ public static final String GMX = "http://www.isotc211.org/2005/gmx"; /** Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java Fri Feb 1 19:34:39 2013 @@ -72,7 +72,7 @@ final class NilObjectHandler implements asList.add(identifier); } } - attribute = new IdentifierMapWithSpecialCases(asList, null); + attribute = new IdentifierMapWithSpecialCases(asList); } /** Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java Fri Feb 1 19:34:39 2013 @@ -31,10 +31,9 @@ import javax.xml.bind.annotation.adapter import org.apache.sis.util.Version; import org.apache.sis.util.CharSequences; import org.apache.sis.util.resources.Errors; +import org.apache.sis.util.collection.CollectionsExt; import org.apache.sis.internal.jaxb.MarshalContext; -import static org.apache.sis.util.collection.Collections.unmodifiableOrCopy; - /** * Base class of {@link PooledMarshaller} and {@link PooledUnmarshaller}. @@ -132,6 +131,13 @@ abstract class Pooled { private int bitMasks; /** + * The {@link System#nanoTime()} value of the last call to {@link #reset()}. + * This is used for disposing (un)marshallers that have not been used for a while, + * since {@code reset()} is invoked just before to push a (un)marshaller in the pool. + */ + volatile long resetTime; + + /** * Default constructor. * * @param internal {@code true} if the JAXB implementation is the one bundled in JDK 6, @@ -153,7 +159,9 @@ abstract class Pooled { } /** - * Resets the (un)marshaller to its initial state. + * Releases resources and resets the (un)marshaller to its initial state. + * This method is invoked by {@link MarshallerPool} just before to push a + * (un)marshaller in the pool after its usage. * * @throws JAXBException If an error occurred while restoring a property. */ @@ -169,6 +177,7 @@ abstract class Pooled { locale = null; timezone = null; bitMasks = initialBitMasks(); + resetTime = System.nanoTime(); } /** @@ -255,7 +264,7 @@ abstract class Pooled { copy.put(key, (String) schema); } } - copy = unmodifiableOrCopy(copy); + copy = CollectionsExt.unmodifiableOrCopy(copy); } schemas = copy; return; Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java Fri Feb 1 19:34:39 2013 @@ -21,7 +21,6 @@ import java.lang.reflect.Proxy; import org.opengis.metadata.Identifier; import org.apache.sis.util.resources.Errors; import org.apache.sis.util.LenientComparable; -import org.apache.sis.internal.jaxb.UUIDs; import org.apache.sis.internal.jaxb.gmx.Anchor; import static org.apache.sis.util.ArgumentChecks.*; @@ -91,9 +90,7 @@ public class ReferenceResolver { /** * Returns an object of the given type for the given {@code uuid} attribute, or {@code null} - * if none. The default implementation looks in an internal map for previously unmarshalled - * object having the given UUID. If no existing instance is found, then this method returns - * {@code null}. + * if none. The default implementation returns {@code null} in all cases. * * @param <T> The compile-time type of the {@code type} argument. * @param context Context (GML version, locale, <i>etc.</i>) of the (un)marshalling process. @@ -106,8 +103,7 @@ public class ReferenceResolver { public <T> T resolve(final MarshalContext context, final Class<T> type, final UUID uuid) { ensureNonNull("type", type); ensureNonNull("uuid", uuid); - final Object object = UUIDs.lookup(uuid); - return type.isInstance(object) ? (T) object : null; + return null; } /** Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/XML.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/XML.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/XML.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/XML.java Fri Feb 1 19:34:39 2013 @@ -17,9 +17,17 @@ package org.apache.sis.xml; import java.util.Locale; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringReader; +import java.io.StringWriter; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; +import javax.xml.bind.JAXBException; import org.apache.sis.util.Static; +import org.apache.sis.internal.util.SystemListener; +import org.apache.sis.internal.jaxb.TypeRegistration; /** @@ -227,8 +235,144 @@ public final class XML extends Static { public static final String STRING_SUBSTITUTES = "org.apache.sis.xml.stringSubstitutes"; /** + * The pool of marshallers and unmarshallers used by this class. + * The field name uses the uppercase convention because this field is almost constant: + * this field is initially null, then created by {@link #getPool()} when first needed. + * Once created the field value usually doesn't change. However the field may be reset + * to {@code null} in an OSGi context when modules are loaded or unloaded, because the + * set of classes returned by {@link TypeRegistration#defaultClassesToBeBound()} may + * have changed. + * + * @see #getPool() + */ + private static volatile MarshallerPool POOL; + + /** + * Registers a listener for classpath changes. In such case, a new pool will need to + * be created because the {@code JAXBContext} may be different. + */ + static { + SystemListener.add(new SystemListener() { + @Override protected void classpathChanged() { + POOL = null; + } + }); + } + + /** * Do not allow instantiation on this class. */ private XML() { } + + /** + * Returns the default (un)marshaller pool used by all methods in this class. + * + * {@note Current implementation uses the double-check idiom. This is usually a deprecated + * practice (the recommended alterative is to use static class initialization), but in this + * particular case the field may be reset to <code>null</code> if OSGi modules are loaded + * or unloaded, so static class initialization would be a little bit too rigid.} + */ + private static MarshallerPool getPool() throws JAXBException { + MarshallerPool pool = POOL; + if (pool == null) { + synchronized (XML.class) { + pool = POOL; // Double-check idiom: see javadoc. + if (pool == null) { + POOL = pool = new MarshallerPool(TypeRegistration.defaultClassesToBeBound()); + } + } + } + return pool; + } + + /** + * Marshall the given object into a string. + * + * @param object The root of content tree to be marshalled. + * @return The XML representation of the given object. + * @throws JAXBException If an error occurred during the marshalling. + */ + public static String marshal(final Object object) throws JAXBException { + final StringWriter output = new StringWriter(); + final MarshallerPool pool = getPool(); + final Marshaller marshaller = pool.acquireMarshaller(); + marshaller.marshal(object, output); + pool.release(marshaller); + return output.toString(); + } + + /** + * Marshall the given object into a stream. + * + * @param object The root of content tree to be marshalled. + * @param output The stream where to write. + * @throws JAXBException If an error occurred during the marshalling. + */ + public static void marshal(final Object object, final OutputStream output) throws JAXBException { + final MarshallerPool pool = getPool(); + final Marshaller marshaller = pool.acquireMarshaller(); + marshaller.marshal(object, output); + pool.release(marshaller); + } + + /** + * Marshall the given object into a file. + * + * @param object The root of content tree to be marshalled. + * @param output The file to be written. + * @throws JAXBException If an error occurred during the marshalling. + */ + public static void marshal(final Object object, final File output) throws JAXBException { + final MarshallerPool pool = getPool(); + final Marshaller marshaller = pool.acquireMarshaller(); + marshaller.marshal(object, output); + pool.release(marshaller); + } + + /** + * Unmarshall an object from the given string. + * + * @param input The XML representation of an object. + * @return The object unmarshalled from the given input. + * @throws JAXBException If an error occurred during the unmarshalling. + */ + public static Object unmarshal(final String input) throws JAXBException { + final StringReader in = new StringReader(input); + final MarshallerPool pool = getPool(); + final Unmarshaller unmarshaller = pool.acquireUnmarshaller(); + final Object object = unmarshaller.unmarshal(in); + pool.release(unmarshaller); + return object; + } + + /** + * Unmarshall an object from the given stream. + * + * @param input The stream from which to read a XML representation. + * @return The object unmarshalled from the given input. + * @throws JAXBException If an error occurred during the unmarshalling. + */ + public static Object unmarshal(final InputStream input) throws JAXBException { + final MarshallerPool pool = getPool(); + final Unmarshaller unmarshaller = pool.acquireUnmarshaller(); + final Object object = unmarshaller.unmarshal(input); + pool.release(unmarshaller); + return object; + } + + /** + * Unmarshall an object from the given file. + * + * @param input The file from which to read a XML representation. + * @return The object unmarshalled from the given input. + * @throws JAXBException If an error occurred during the unmarshalling. + */ + public static Object unmarshal(final File input) throws JAXBException { + final MarshallerPool pool = getPool(); + final Unmarshaller unmarshaller = pool.acquireUnmarshaller(); + final Object object = unmarshaller.unmarshal(input); + pool.release(unmarshaller); + return object; + } } Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCasesTest.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCasesTest.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCasesTest.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCasesTest.java Fri Feb 1 19:34:39 2013 @@ -57,7 +57,7 @@ public final strictfp class IdentifierMa */ @Override IdentifierMapAdapter create(final Collection<Identifier> identifiers) { - return new IdentifierMapWithSpecialCases(identifiers, null); + return new IdentifierMapWithSpecialCases(identifiers); } /** @@ -110,25 +110,19 @@ public final strictfp class IdentifierMa } /** - * Tests the binding of UUID. + * Tests with UUIDs. */ @Test public void testUUIDs() { - final String object = "IdentifiedObject"; final List<Identifier> identifiers = new ArrayList<Identifier>(); - final IdentifierMap map = new IdentifierMapWithSpecialCases(identifiers, object); + final IdentifierMap map = new IdentifierMapWithSpecialCases(identifiers); final UUID id1 = UUID.fromString("434f3107-c6d2-4c8c-bb25-553f68641c5c"); final UUID id2 = UUID.fromString("42924124-032a-4dfe-b06e-113e3cb81cf0"); // Add first UUID. - assertNull("Shall not contain UUID before put.", UUIDs.lookup(id1)); assertNull(map.putSpecialized(IdentifierSpace.UUID, id1)); - assertSame("Object sholl be associated to UUID.", object, UUIDs.lookup(id1)); // Replace UUID by a new one. - assertNull("Shall not contain UUID before put.", UUIDs.lookup(id2)); assertSame(id1, map.putSpecialized(IdentifierSpace.UUID, id2)); - assertNull("Shall not contain the removed UUID.", UUIDs.lookup(id1)); - assertSame("Object sholl be associated to UUID.", object, UUIDs.lookup(id2)); } } Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java Fri Feb 1 19:34:39 2013 @@ -23,7 +23,7 @@ import org.apache.sis.test.DependsOnMeth import static org.junit.Assert.*; import static org.apache.sis.math.MathFunctions.*; -import static org.apache.sis.util.Arrays.isSorted; +import static org.apache.sis.util.ArraysExt.isSorted; /** @@ -34,7 +34,7 @@ import static org.apache.sis.util.Arrays * @version 0.3 * @module */ -@DependsOn(org.apache.sis.util.ArraysTest.class) +@DependsOn(org.apache.sis.util.ArraysExtTest.class) public final strictfp class MathFunctionsTest extends TestCase { /** * Small number for floating point comparisons. Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java Fri Feb 1 19:34:39 2013 @@ -37,9 +37,10 @@ import org.junit.runners.model.Initializ import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; -import static org.apache.sis.util.Arrays.resize; -import static org.apache.sis.util.collection.Collections.isNullOrEmpty; -import static org.apache.sis.util.collection.Collections.hashMapCapacity; +import org.apache.sis.util.ArraysExt; + +import static org.apache.sis.util.collection.CollectionsExt.isNullOrEmpty; +import static org.apache.sis.util.collection.CollectionsExt.hashMapCapacity; /** @@ -247,7 +248,7 @@ public final class TestRunner extends Bl if (count == 0) { throw new NoTestsRemainException(); } - filteredChildren = resize(children, count); + filteredChildren = ArraysExt.resize(children, count); } /** Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java Fri Feb 1 19:34:39 2013 @@ -34,7 +34,7 @@ import org.junit.runners.Suite; org.apache.sis.internal.test.XMLComparatorTest.class, // Most basic functions of SIS library. - org.apache.sis.util.ArraysTest.class, + org.apache.sis.util.ArraysExtTest.class, org.apache.sis.util.CharactersTest.class, org.apache.sis.util.CharSequencesTest.class, org.apache.sis.util.StringBuildersTest.class, Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java Fri Feb 1 19:34:39 2013 @@ -38,7 +38,7 @@ import static org.apache.sis.util.CharSe * @module */ @DependsOn({ - ArraysTest.class, + ArraysExtTest.class, CharactersTest.class }) public final strictfp class CharSequencesTest extends TestCase { Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/util/LocalesTest.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/util/LocalesTest.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/util/LocalesTest.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/util/LocalesTest.java Fri Feb 1 19:34:39 2013 @@ -32,7 +32,7 @@ import static org.junit.Assert.*; * @version 0.3 * @module */ -@DependsOn(Arrays.class) +@DependsOn(ArraysExt.class) public final strictfp class LocalesTest extends TestCase { /** * Tests the {@link Locales#getAvailableLanguages()} method. @@ -40,8 +40,8 @@ public final strictfp class LocalesTest @Test public void testGetAvailableLanguages() { final Locale[] locales = Locales.ALL.getAvailableLanguages(); - assertTrue ("Expected English locale.", Arrays.contains(locales, Locale.ENGLISH)); - assertFalse("US is a country, not a language.", Arrays.contains(locales, Locale.US)); + assertTrue ("Expected English locale.", ArraysExt.contains(locales, Locale.ENGLISH)); + assertFalse("US is a country, not a language.", ArraysExt.contains(locales, Locale.US)); } /** @@ -50,11 +50,11 @@ public final strictfp class LocalesTest @Test public void testGetAvailableLocales() { final Locale[] locales = Locales.SIS.getAvailableLocales(); - assertTrue(Arrays.contains(locales, Locale.ENGLISH)); - assertTrue(Arrays.contains(locales, Locale.US)); - assertTrue(Arrays.contains(locales, Locale.CANADA)); - assertTrue(Arrays.contains(locales, Locale.FRANCE)); - assertTrue(Arrays.contains(locales, Locale.CANADA_FRENCH)); + assertTrue(ArraysExt.contains(locales, Locale.ENGLISH)); + assertTrue(ArraysExt.contains(locales, Locale.US)); + assertTrue(ArraysExt.contains(locales, Locale.CANADA)); + assertTrue(ArraysExt.contains(locales, Locale.FRANCE)); + assertTrue(ArraysExt.contains(locales, Locale.CANADA_FRENCH)); } /** Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/WeakHashSetTest.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/WeakHashSetTest.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/WeakHashSetTest.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/WeakHashSetTest.java Fri Feb 1 19:34:39 2013 @@ -38,7 +38,7 @@ import static org.apache.sis.test.TestUt * @version 0.3 * @module */ -@DependsOn(org.apache.sis.util.ArraysTest.class) +@DependsOn(org.apache.sis.util.ArraysExtTest.class) public final strictfp class WeakHashSetTest extends TestCase { /** * The size of the test sets to be created. Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/WeakValueHashMapTest.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/WeakValueHashMapTest.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/WeakValueHashMapTest.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/WeakValueHashMapTest.java Fri Feb 1 19:34:39 2013 @@ -39,7 +39,7 @@ import static org.apache.sis.test.TestUt * @version 0.3 * @module */ -@DependsOn(org.apache.sis.util.ArraysTest.class) +@DependsOn(org.apache.sis.util.ArraysExtTest.class) public final strictfp class WeakValueHashMapTest extends TestCase { /** * The size of the test sets to be created. Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java Fri Feb 1 19:34:39 2013 @@ -40,7 +40,7 @@ import static org.apache.sis.test.Assert * @since 0.3 (derived from geotk-2.2) * @version 0.3 */ -@DependsOn(org.apache.sis.util.ArraysTest.class) +@DependsOn(org.apache.sis.util.ArraysExtTest.class) public final strictfp class IndexedResourceBundleTest extends TestCase { /** * The resource bundle in process of being tested. Shall be reset to {@code null} after every Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/xml/NilReasonTest.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/xml/NilReasonTest.java?rev=1441597&r1=1441596&r2=1441597&view=diff ============================================================================== --- sis/trunk/sis-utility/src/test/java/org/apache/sis/xml/NilReasonTest.java (original) +++ sis/trunk/sis-utility/src/test/java/org/apache/sis/xml/NilReasonTest.java Fri Feb 1 19:34:39 2013 @@ -21,7 +21,7 @@ import org.opengis.metadata.citation.Cit import org.opengis.metadata.citation.ResponsibleParty; import org.apache.sis.util.LenientComparable; import org.apache.sis.util.ComparisonMode; -import org.apache.sis.util.Arrays; +import org.apache.sis.util.ArraysExt; import org.apache.sis.test.TestCase; import org.junit.*; @@ -50,8 +50,8 @@ public final strictfp class NilReasonTes assertSame(NilReason.MISSING, NilReason.valueOf(" missing ")); final NilReason[] reasons = NilReason.values(); - assertTrue(Arrays.contains(reasons, NilReason.TEMPLATE)); - assertTrue(Arrays.contains(reasons, NilReason.MISSING)); + assertTrue(ArraysExt.contains(reasons, NilReason.TEMPLATE)); + assertTrue(ArraysExt.contains(reasons, NilReason.MISSING)); } /** @@ -70,9 +70,9 @@ public final strictfp class NilReasonTes assertNull ("NilReason.getURI()", other.getURI()); final NilReason[] reasons = NilReason.values(); - assertTrue(Arrays.contains(reasons, NilReason.TEMPLATE)); - assertTrue(Arrays.contains(reasons, NilReason.MISSING)); - assertTrue(Arrays.contains(reasons, other)); + assertTrue(ArraysExt.contains(reasons, NilReason.TEMPLATE)); + assertTrue(ArraysExt.contains(reasons, NilReason.MISSING)); + assertTrue(ArraysExt.contains(reasons, other)); } /** @@ -88,9 +88,9 @@ public final strictfp class NilReasonTes assertEquals("NilReason.getURI()", "http://www.nilreasons.org", String.valueOf(other.getURI())); final NilReason[] reasons = NilReason.values(); - assertTrue(Arrays.contains(reasons, NilReason.TEMPLATE)); - assertTrue(Arrays.contains(reasons, NilReason.MISSING)); - assertTrue(Arrays.contains(reasons, other)); + assertTrue(ArraysExt.contains(reasons, NilReason.TEMPLATE)); + assertTrue(ArraysExt.contains(reasons, NilReason.MISSING)); + assertTrue(ArraysExt.contains(reasons, other)); } /**
