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 2016/01/08 19:29:07 UTC
svn commit: r1723780 [9/12] - in /sis/branches/JDK7: ./
application/sis-console/src/main/artifact/bin/
application/sis-console/src/main/artifact/log/
application/sis-console/src/main/java/org/apache/sis/console/
core/sis-build-helper/src/main/java/org/...
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/ServletListener.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/ServletListener.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/ServletListener.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/ServletListener.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -16,7 +16,6 @@
*/
package org.apache.sis.internal.system;
-import javax.management.JMException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@@ -28,7 +27,7 @@ import javax.servlet.annotation.WebListe
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.7
* @module
*
* @see OSGiActivator
@@ -42,6 +41,8 @@ public final class ServletListener imple
*/
@Override
public void contextInitialized(final ServletContextEvent event) {
+ final String env = event.getServletContext().getServerInfo();
+ Shutdown.setContainer(env != null ? env : "Servlet");
}
/**
@@ -53,7 +54,7 @@ public final class ServletListener imple
public void contextDestroyed(final ServletContextEvent event) {
try {
Shutdown.stop(getClass());
- } catch (JMException e) {
+ } catch (Exception e) {
event.getServletContext().log(e.toString(), e);
}
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -16,48 +16,180 @@
*/
package org.apache.sis.internal.system;
-import javax.management.JMException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.concurrent.Callable;
import org.apache.sis.util.logging.Logging;
+// Branch-dependent imports
+import java.util.Objects;
+
/**
* A central place where to manage SIS shutdown process.
- * For now this class is not yet registered as a shutdown hock,
- * but it will be in a future version.
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.7
* @module
*/
-public final class Shutdown {
+public final class Shutdown extends Thread {
+ /**
+ * Non-null if a shutdown hook is already registered. That shutdown hook is not necessarily {@link #hook}.
+ * It may be an OSGi or Servlet shutdown hook instead, as notified by {@link #setContainer(String)}.
+ */
+ private static String container;
+
+ /**
+ * The shutdown hook to be registered to the JVM {@link Runtime}, created when first needed.
+ */
+ private static Shutdown hook;
+
/**
- * Do not allow instantiation of this class.
+ * The resources to dispose. Most recently added resources are last.
+ */
+ private static final List<Callable<?>> resources = new ArrayList<>();
+
+ /**
+ * Creates the thread to be executed at shutdown time.
*/
private Shutdown() {
+ super(Threads.SIS, "Shutdown");
}
/**
- * Shutdowns the {@code sis-utility} threads and unregister the supervisor MBean.
+ * Invoked at JVM shutdown time.
+ */
+ @Override
+ @SuppressWarnings("CallToPrintStackTrace")
+ public void run() {
+ try {
+ Shutdown.stop((Class<?>) null);
+ } catch (Exception e) {
+ /*
+ * Too late for logging since we are in process of shutting down the Java Virtual Machine.
+ * It is still possible to write the stack trace to System.err, but this is about all we can do.
+ */
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Returns the value set by the last call to {@link #setContainer(String)}.
+ *
+ * @return Typically {@code "OSGi"}, {@code "Servlet"} or {@code null}.
+ */
+ public static String getContainer() {
+ synchronized (resources) {
+ return container;
+ }
+ }
+
+ /**
+ * Invoked if the Apache SIS library is executed from an environment that provide its own shutdown hook.
+ * Example of such environments are OSG and servlet containers. In such case, the shutdown hook will not
+ * be registered to the JVM {@link Runtime}.
*
- * @param caller The class invoking this method, to be used only for logging purpose,
- * or {@code null} if the logging system is not available anymore (i.e. the JVM
- * itself is shutting down).
- * @throws JMException If an error occurred during unregistration of the supervisor MBean.
+ * @param env A description of the container. Should contain version information if possible.
+ * Example: {@code "OSGi"} or {@code "JavaServer Web Dev Kit/1.0"}.
*/
- public static void stop(final Class<?> caller) throws JMException {
+ public static void setContainer(final String env) {
+ Objects.requireNonNull(env);
+ synchronized (resources) {
+ removeShutdownHook(); // Should not be needed but we are paranoiac.
+ container = env;
+ }
+ }
+
+ /**
+ * Registers a code to execute at JVM shutdown time. The resources will be disposed at
+ * shutdown time in reverse order (most recently added resources will be disposed first).
+ *
+ * <p>The same resource shall not be added twice.</p>
+ *
+ * @param resource The resource disposal to register for execution at shutdown time.
+ */
+ public static void register(final Callable<?> resource) {
+ synchronized (resources) {
+ assert !resources.contains(resource);
+ resources.add(resource);
+ if (hook == null && container == null) {
+ hook = new Shutdown();
+ Runtime.getRuntime().addShutdownHook(hook);
+ }
+ }
+ }
+
+ /**
+ * Removes the shutdown hook, if any.
+ */
+ private static void removeShutdownHook() {
+ assert Thread.holdsLock(resources);
+ if (hook != null) {
+ Runtime.getRuntime().removeShutdownHook(hook);
+ hook = null;
+ }
+ }
+
+ /**
+ * Unregisters a code from execution at JVM shutdown time.
+ * This method uses identity comparison (it does not use {@link Object#equals(Object)}).
+ *
+ * @param resource The resource disposal to cancel execution.
+ */
+ public static void unregister(final Callable<?> resource) {
+ synchronized (resources) {
+ for (int i = resources.size(); --i>=0;) { // Check most recently added resources first.
+ if (resources.get(i) == resource) {
+ resources.remove(i);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Unregister the supervisor MBean, executes the disposal tasks and shutdowns the {@code sis-utility} threads.
+ *
+ * @param caller The class invoking this method, to be used only for logging purpose, or {@code null}
+ * if the logging system is not available anymore (i.e. the JVM itself is shutting down).
+ * @throws Exception If an error occurred during unregistration of the supervisor MBean
+ * or during a resource disposal.
+ */
+ public static void stop(final Class<?> caller) throws Exception {
+ synchronized (resources) {
+ container = "Shutdown";
+ if (caller != null) {
+ removeShutdownHook();
+ }
+ }
/*
* Unregister the MBean before to stop the threads, in order to avoid false alerts
* in the superviror 'warnings()' method. Failure to unregister the MBean is worth
* to report, but we will do that only after we completed the other shutdown steps.
*/
- JMException exception = null;
+ Exception exception = null;
if (Supervisor.ENABLED) try {
Supervisor.unregister();
- } catch (JMException deferred) {
+ } catch (Exception deferred) {
exception = deferred;
}
/*
+ * Dispose resources, if any, starting with most recently registered. The disposal code should not
+ * invoke Shutdown.[un]register(Disposable), but we nevertheless make the loop robust to this case.
+ */
+ synchronized (resources) {
+ int i;
+ while ((i = resources.size()) != 0) try { // In case run() modifies the resources list.
+ resources.remove(i - 1).call(); // Dispose most recently added resources first.
+ } catch (Exception e) {
+ if (exception != null) {
+ e.addSuppressed(exception);
+ }
+ exception = e;
+ }
+ }
+ /*
* Following is usually fast, but may potentially take a little while.
* If an other thread invoked Thread.interrupt() while we were waiting
* for the threads to terminate, maybe not all threads have terminated
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -37,7 +37,6 @@ import javax.management.InstanceAlreadyE
import java.lang.management.ManagementFactory;
import org.apache.sis.setup.About;
-import org.apache.sis.util.Localized;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.resources.Messages;
@@ -52,10 +51,10 @@ import org.apache.sis.util.collection.Tr
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.4
+ * @version 0.7
* @module
*/
-public final class Supervisor extends StandardMBean implements SupervisorMBean, Localized {
+public final class Supervisor extends StandardMBean implements SupervisorMBean {
/**
* Whatever JMX agent is enabled. Setting this variable to {@code false} allows the
* Java compiler to omit any dependency to this {@code Supervisor} class.
@@ -82,13 +81,13 @@ public final class Supervisor extends St
* and the MBean will not be registered. This method does not propagate the exception
* because the MBean is not a mandatory part of SIS library.</p>
*/
- static synchronized void register() {
+ public static synchronized void register() {
if (name == null) {
name = ObjectName.WILDCARD; // In case of failure.
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
try {
final ObjectName n = new ObjectName(NAME);
- server.registerMBean(new Supervisor(null, null), n);
+ server.registerMBean(new Supervisor(), n);
name = n; // Store only on success.
} catch (InstanceAlreadyExistsException e) {
final LogRecord record = Messages.getResources(null)
@@ -119,34 +118,12 @@ public final class Supervisor extends St
}
/**
- * The locale for producing the messages, or {@code null} for the default.
- */
- private final Locale locale;
-
- /**
- * The timezone for formatting the dates, or {@code null} for the default.
- */
- private final TimeZone timezone;
-
- /**
- * Creates a new {@code Supervisor} which will report messages in the given locale.
+ * Creates a new {@code Supervisor}.
*
- * @param locale The locale to use for reporting messages, or {@code null} for the default.
- * @param timezone The timezone for formatting the dates, or {@code null} for the default.
* @throws NotCompliantMBeanException Should never happen.
*/
- public Supervisor(final Locale locale, final TimeZone timezone) throws NotCompliantMBeanException {
+ public Supervisor() throws NotCompliantMBeanException {
super(SupervisorMBean.class);
- this.locale = locale;
- this.timezone = timezone;
- }
-
- /**
- * Returns the supervisor locale, or {@code null} for the default locale.
- */
- @Override
- public Locale getLocale() {
- return locale;
}
/**
@@ -210,7 +187,7 @@ public final class Supervisor extends St
*/
private String getDescription(final String resourceKey) {
return ResourceBundle.getBundle("org.apache.sis.internal.system.Descriptions",
- (locale != null) ? locale : Locale.getDefault(Locale.Category.DISPLAY),
+ Locale.getDefault(Locale.Category.DISPLAY),
Supervisor.class.getClassLoader()).getString(resourceKey);
}
@@ -222,15 +199,15 @@ public final class Supervisor extends St
* {@inheritDoc}
*/
@Override
- public TreeTable configuration() {
- return About.configuration(EnumSet.allOf(About.class), locale, timezone);
+ public TreeTable configuration(final EnumSet<About> sections, final Locale locale, final TimeZone timezone) {
+ return About.configuration(sections, locale, timezone);
}
/**
* {@inheritDoc}
*/
@Override
- public String[] warnings() {
+ public String[] warnings(final Locale locale) {
final DaemonThread lastCreatedDaemon;
synchronized (Threads.class) {
lastCreatedDaemon = Threads.lastCreatedDaemon;
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/SupervisorMBean.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/SupervisorMBean.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/SupervisorMBean.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/SupervisorMBean.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -16,6 +16,10 @@
*/
package org.apache.sis.internal.system;
+import java.util.EnumSet;
+import java.util.Locale;
+import java.util.TimeZone;
+import org.apache.sis.setup.About;
import org.apache.sis.util.collection.TreeTable;
@@ -24,7 +28,7 @@ import org.apache.sis.util.collection.Tr
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.7
* @module
*/
public interface SupervisorMBean {
@@ -35,15 +39,19 @@ public interface SupervisorMBean {
* Apache SIS version, Java version and operation system version; a "Classpath"
* section containing bootstrap, extension and user classpath, <i>etc</i>.
*
+ * @param sections The section for which information are desired.
+ * @param locale The locale to use for formatting the texts in the tree, or {@code null} for the default.
+ * @param timezone The timezone to use for formatting the dates, or {@code null} for the default.
* @return Configuration information, as a tree for grouping some configuration by sections.
*/
- TreeTable configuration();
+ TreeTable configuration(EnumSet<About> sections, Locale locale, TimeZone timezone);
/**
* If there is something wrong with the current Apache SIS status,
* returns descriptions of the problems. Otherwise returns {@code null}.
*
+ * @param locale The locale to use for reporting messages, or {@code null} for the default.
* @return A description of a problems in the library, or {@code null} if none.
*/
- String[] warnings();
+ String[] warnings(Locale locale);
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Threads.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Threads.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Threads.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Threads.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -16,8 +16,6 @@
*/
package org.apache.sis.internal.system;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ExecutorService;
import org.apache.sis.util.Static;
import org.apache.sis.util.logging.Logging;
@@ -34,7 +32,7 @@ import org.apache.sis.util.logging.Loggi
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.7
* @module
*/
final class Threads extends Static {
@@ -83,19 +81,6 @@ final class Threads extends Static {
static DaemonThread lastCreatedDaemon;
/**
- * Executor to shutdown. This is a copy of the {@code <removed class>} executor static final
- * field, copied here only when the {@code <removed class>} class is loaded and initialized.
- * We proceed that way for avoiding dependency from {@code Threads} to {@code <removed class>}.
- *
- * <p>This field has been temporarily fixed to {@code null} since we removed executor as of
- * <a href="https://issues.apache.org/jira/browse/SIS-76">SIS-76</a>. However we may revert
- * to a modifiable field in a future version if we choose to use executor again. In the main
- * time, we declare this field as {@code final} for allowing the Javac compiler to omit all
- * compiled code inside {@code if (executor != null)} block.</p>
- */
- private static final ExecutorService executor = null;
-
- /**
* Do not allows instantiation of this class.
*/
private Threads() {
@@ -114,20 +99,6 @@ final class Threads extends Static {
* we were waiting for the daemon threads to die.
*/
static synchronized void shutdown(final long stopWaitingAt) throws InterruptedException {
- if (executor != null) {
- executor.shutdown();
- /*
- * Wait for work completion. In theory this is not necessary since the daemon
- * tasks are only house-cleaning work. We nevertheless wait for their completion
- * as a safety. There tasks are supposed to be short.
- */
- final long delay = stopWaitingAt - System.nanoTime();
- if (delay > 0) {
- executor.awaitTermination(delay, TimeUnit.NANOSECONDS);
- // Even if the tasks didn't completed, continue without waiting for them.
- // We can not log at this point, since the logging framework may be shutdown.
- }
- }
DaemonThread.killAll(lastCreatedDaemon, stopWaitingAt);
}
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/package-info.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/package-info.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/package-info.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -25,7 +25,7 @@
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.7
* @module
*/
package org.apache.sis.internal.system;
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -32,7 +32,7 @@ import org.apache.sis.util.Static;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.5
- * @version 0.6
+ * @version 0.7
* @module
*/
public final class Constants extends Static {
@@ -78,6 +78,16 @@ public final class Constants extends Sta
public static final byte CRS84 = 84;
/**
+ * The {@code CRS:88} identifier for a coordinate reference system.
+ */
+ public static final byte CRS88 = 88;
+
+ /**
+ * The {@code CRS:1} identifier for a coordinate reference system.
+ */
+ public static final byte CRS1 = 1;
+
+ /**
* The NetCDF parameter name for the Earth radius.
*/
public static final String EARTH_RADIUS = "earth_radius";
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -21,6 +21,9 @@ import org.apache.sis.math.MathFunctions
import org.apache.sis.math.DecimalFunctions;
// No BigDecimal dependency - see class javadoc
+// Branch-dependent imports
+import org.apache.sis.internal.jdk8.JDK8;
+
/**
* Basic arithmetic methods for extended precision numbers using the <cite>double-double</cite> algorithm.
@@ -284,7 +287,7 @@ public final class DoubleDouble extends
@Override public double doubleValue() {return value;}
@Override public float floatValue() {return (float) value;}
@Override public long longValue() {return Math.round(value);}
- @Override public int intValue() {return (int) longValue();}
+ @Override public int intValue() {return JDK8.toIntExact(longValue());}
/**
* Suggests an {@link #error} for the given value. The {@code DoubleDouble} class contains a hard-coded list
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -25,6 +25,9 @@ import org.apache.sis.util.ComparisonMod
import static java.lang.Math.max;
import static java.lang.Math.abs;
+// Branch-dependent imports
+import org.apache.sis.internal.jdk8.JDK8;
+
/**
* Miscellaneous utilities methods working on floating point numbers.
@@ -180,7 +183,7 @@ public final class Numerics extends Stat
if (data == null) return null;
final int[] result = new int[data.length];
for (int i=0; i<data.length; i++) {
- result[i] = (int) Math.round(data[i]);
+ result[i] = JDK8.toIntExact(Math.round(data[i]));
}
return result;
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -120,6 +120,7 @@ public enum X364 {
* @param code The X.364 numerical code.
* @param color The color name, or {@code null} if none.
*/
+ @SuppressWarnings("ThisEscapedInObjectConstruction")
private X364(final byte code, final String color) {
this.code = code;
this.color = color;
@@ -132,6 +133,7 @@ public enum X364 {
*
* @param foreground The X.364 code for a foreground color.
*/
+ @SuppressWarnings("ThisEscapedInObjectConstruction")
private X364(final X364 foreground) {
this((byte) (foreground.code + 10), foreground.color);
this.foreground = foreground;
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Line.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Line.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Line.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Line.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -28,8 +28,8 @@ import static java.lang.Double.*;
/**
* Equation of a line in a two dimensional space (<var>x</var>,<var>y</var>).
- * A line can be expressed by the <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y</var>₀ equation
- * where <var>y</var>₀ is the value of <var>y</var> at <var>x</var> = 0.
+ * A line can be expressed by the <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y₀</var> equation
+ * where <var>y₀</var> is the value of <var>y</var> at <var>x</var> = 0.
*
* <p>The equation parameters for a {@code Line} object can be set at construction time or using one
* of the {@code setLine(…)} methods. The <var>y</var> value can be computed for a given <var>x</var>
@@ -37,8 +37,8 @@ import static java.lang.Double.*;
* work even if the line is vertical.</p>
*
* <div class="note"><b>Comparison with Java2D geometries:</b>
- * At the difference of {@link java.awt.geom.Line2D} which is bounded by (<var>x</var>₁,<var>y</var>₁)
- * and (<var>x</var>₂,<var>y</var>₂) points, {@code Line} objects extend toward infinity.</div>
+ * At the difference of {@link java.awt.geom.Line2D} which is bounded by (<var>x₁</var>,<var>y₁</var>)
+ * and (<var>x₂</var>,<var>y₂</var>) points, {@code Line} objects extend toward infinity.</div>
*
* @author Martin Desruisseaux (MPO, IRD)
* @since 0.5
@@ -84,7 +84,7 @@ public class Line implements Cloneable,
/**
* Constructs a line with the specified slope and offset.
- * The linear equation will be <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y</var>₀.
+ * The linear equation will be <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y₀</var>.
*
* @param slope The slope.
* @param y0 The <var>y</var> value at <var>x</var> = 0.
@@ -111,7 +111,7 @@ public class Line implements Cloneable,
/**
* Returns the <var>x</var> value for <var>y</var> = 0.
- * Coordinate (<var>x</var>₀, 0) is the intersection point with the <var>x</var> axis.
+ * Coordinate (<var>x₀</var>, 0) is the intersection point with the <var>x</var> axis.
*
* @return The <var>x</var> value for <var>y</var> = 0.
*
@@ -137,7 +137,7 @@ public class Line implements Cloneable,
/**
* Returns the <var>y</var> value for <var>x</var> = 0.
- * Coordinate (0, <var>y</var>₀) is the intersection point with the <var>y</var> axis.
+ * Coordinate (0, <var>y₀</var>) is the intersection point with the <var>y</var> axis.
*
* @return The <var>y</var> value for <var>x</var> = 0.
*
@@ -179,7 +179,7 @@ public class Line implements Cloneable,
/**
* Sets this line to the specified slope and offset.
- * The linear equation will be <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y</var>₀.
+ * The linear equation will be <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y₀</var>.
*
* @param slope The slope.
* @param y0 The <var>y</var> value at <var>x</var> = 0.
@@ -218,7 +218,7 @@ public class Line implements Cloneable,
/**
* Given a set of data points <var>x</var>[0 … <var>n</var>-1], <var>y</var>[0 … <var>n</var>-1],
- * fits them to a straight line <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y</var>₀ in a
+ * fits them to a straight line <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y₀</var> in a
* least-squares senses. This method assume that the <var>x</var> values are precise and all uncertainty
* is in <var>y</var>.
*
@@ -235,7 +235,7 @@ public class Line implements Cloneable,
/**
* Given a sequence of points, fits them to a straight line <var>y</var> = <var>slope</var>⋅<var>x</var> +
- * <var>y</var>₀ in a least-squares senses. This method assume that the <var>x</var> values are precise and
+ * <var>y₀</var> in a least-squares senses. This method assume that the <var>x</var> values are precise and
* all uncertainty is in <var>y</var>.
*
* <p>Points shall be two dimensional with ordinate values in the (<var>x</var>,<var>y</var>) order.
@@ -382,7 +382,7 @@ public class Line implements Cloneable,
/**
* Returns a string representation of this line. This method returns the linear equation
- * in the form <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y</var>₀.
+ * in the form <var>y</var> = <var>slope</var>⋅<var>x</var> + <var>y₀</var>.
*
* @return A string representation of this line.
*/
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -35,7 +35,7 @@ import static java.lang.Math.ulp;
*
* <blockquote>
* <var>{@linkplain #z(double, double) z}</var>(<var>x</var>,<var>y</var>) =
- * <var>sx</var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <var>z</var>₀
+ * <var>sx</var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <var>z₀</var>
* </blockquote>
*
* Those coefficients can be set directly, or computed by a linear regression of this plane
@@ -83,19 +83,19 @@ public class Plane implements Cloneable,
/**
* The slope along the <var>x</var> values. This coefficient appears in the plane equation
- * <var><b><u>sx</u></b></var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <var>z</var>₀.
+ * <var><b><u>sx</u></b></var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <var>z₀</var>.
*/
private double sx;
/**
* The slope along the <var>y</var> values. This coefficient appears in the plane equation
- * <var>sx</var>⋅<var>x</var> + <var><b><u>sy</u></b></var>⋅<var>y</var> + <var>z</var>₀.
+ * <var>sx</var>⋅<var>x</var> + <var><b><u>sy</u></b></var>⋅<var>y</var> + <var>z₀</var>.
*/
private double sy;
/**
* The <var>z</var> value at (<var>x</var>,<var>y</var>) = (0,0). This coefficient appears in the plane equation
- * <var>sx</var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <b><u><var>z</var>₀</u></b>.
+ * <var>sx</var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <b><u><var>z₀</var></u></b>.
*/
private double z0;
@@ -123,7 +123,7 @@ public class Plane implements Cloneable,
/**
* Returns the slope along the <var>x</var> values. This coefficient appears in the plane equation
- * <var><b><u>sx</u></b></var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <var>z</var>₀.
+ * <var><b><u>sx</u></b></var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <var>z₀</var>.
*
* @return The <var>sx</var> term.
*/
@@ -133,7 +133,7 @@ public class Plane implements Cloneable,
/**
* Returns the slope along the <var>y</var> values. This coefficient appears in the plane equation
- * <var>sx</var>⋅<var>x</var> + <var><b><u>sy</u></b></var>⋅<var>y</var> + <var>z</var>₀.
+ * <var>sx</var>⋅<var>x</var> + <var><b><u>sy</u></b></var>⋅<var>y</var> + <var>z₀</var>.
*
* @return The <var>sy</var> term.
*/
@@ -143,9 +143,9 @@ public class Plane implements Cloneable,
/**
* Returns the <var>z</var> value at (<var>x</var>,<var>y</var>) = (0,0). This coefficient appears in the
- * plane equation <var>sx</var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <b><var>z</var>₀</b>.
+ * plane equation <var>sx</var>⋅<var>x</var> + <var>sy</var>⋅<var>y</var> + <b><var>z₀</var></b>.
*
- * @return The <var>z</var>₀ term.
+ * @return The <var>z₀</var> term.
*
* @see #z(double, double)
*/
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Statistics.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Statistics.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Statistics.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/Statistics.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -429,7 +429,7 @@ public class Statistics implements Doubl
/**
* Returns the standard deviation. If the sample values given to the {@code accept(…)}
* methods have a uniform distribution, then the returned value should be close to
- * <code>sqrt({@linkplain #span() span}<sup>2</sup> / 12)</code>. If they have a
+ * <code>sqrt({@linkplain #span() span}² / 12)</code>. If they have a
* Gaussian distribution (which is the most common case), then the returned value
* is related to the <a href="http://en.wikipedia.org/wiki/Error_function">error
* function</a>.
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -43,6 +43,7 @@ import static org.apache.sis.math.Decima
// Branch-dependent imports
import java.util.Objects;
+import org.apache.sis.internal.jdk8.JDK8;
/**
@@ -1044,12 +1045,12 @@ public class AngleFormat extends Format
}
final Number userObject;
if (hasMore) {
- userObject = Integer.valueOf((int) Math.round(value));
+ userObject = JDK8.toIntExact(Math.round(value));
} else {
// Use Float instead of Double because we don't want to give a false impression of accuracy
// (when formatting the seconds field, at least the 10 last bits of the 'double' value are
// non-significant).
- userObject = Float.valueOf((float) value);
+ userObject = (float) value;
}
it.addFieldLimit(Field.forCode(field), userObject, startPosition);
} else {
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -47,7 +47,7 @@ import static org.apache.sis.util.CharSe
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.3
- * @version 0.4
+ * @version 0.7
* @module
*/
public final class Units extends Static {
@@ -70,6 +70,11 @@ public final class Units extends Static
public static final Unit<Duration> MILLISECOND = SI.MetricPrefix.MILLI(SI.SECOND);
/**
+ * The EPSG::1029 definition of year.
+ */
+ private static final Unit<Duration> YEAR = SI.SECOND.divide(31556925.445);
+
+ /**
* Parts per million.
*
* <p>This unit does not have an easily readable symbol because of the
@@ -242,27 +247,27 @@ public final class Units extends Static
* <li>This method tries to returns unique instances for some common units.</li>
* </ul>
*
- * @param <A> The quantity measured by the unit.
+ * @param <Q> The quantity measured by the unit.
* @param unit The unit to multiply.
* @param factor The multiplication factor.
* @return The unit multiplied by the given factor.
*/
@Workaround(library="JSR-275", version="0.9.3")
@SuppressWarnings("unchecked")
- public static <A extends Quantity> Unit<A> multiply(Unit<A> unit, final double factor) {
+ public static <Q extends Quantity> Unit<Q> multiply(Unit<Q> unit, final double factor) {
if (SI.RADIAN.equals(unit)) {
if (abs(factor - (PI / 180)) <= (EPS * PI/180)) {
- return (Unit<A>) NonSI.DEGREE_ANGLE;
+ return (Unit<Q>) NonSI.DEGREE_ANGLE;
}
if (abs(factor - (PI / 200)) <= (EPS * PI/200)) {
- return (Unit<A>) NonSI.GRADE;
+ return (Unit<Q>) NonSI.GRADE;
}
} else if (SI.METRE.equals(unit)) {
if (abs(factor - 0.3048) <= (EPS * 0.3048)) {
- return (Unit<A>) NonSI.FOOT;
+ return (Unit<Q>) NonSI.FOOT;
}
if (abs(factor - (1200.0/3937)) <= (EPS * (1200.0/3937))) {
- return (Unit<A>) NonSI.FOOT_SURVEY_US;
+ return (Unit<Q>) NonSI.FOOT_SURVEY_US;
}
}
if (abs(factor - 1) > EPS) {
@@ -289,13 +294,13 @@ public final class Units extends Static
* since a measurement in kilometres must be multiplied by 1000 in order to give the equivalent
* measurement in the "standard" units (here <var>metres</var>).</p>
*
- * @param <A> The quantity measured by the unit.
+ * @param <Q> The quantity measured by the unit.
* @param unit The unit for which we want the multiplication factor to standard unit.
* @return The factor by which to multiply a measurement in the given unit in order to
* get an equivalent measurement in the standard unit.
*/
@Workaround(library="JSR-275", version="0.9.3")
- public static <A extends Quantity> double toStandardUnit(final Unit<A> unit) {
+ public static <Q extends Quantity> double toStandardUnit(final Unit<Q> unit) {
return derivative(unit.getConverterTo(unit.toSI()), 0);
}
@@ -364,7 +369,7 @@ public final class Units extends Static
*/
if (isURI(uom)) {
String code = DefinitionURI.codeOf("uom", Constants.EPSG, uom);
- if (code != null && code != uom) try { // Really identity check, see above comment.
+ if (code != null && code != uom) try { // Really identity check, see above comment.
return valueOfEPSG(Integer.parseInt(code));
} catch (NumberFormatException e) {
throw new IllegalArgumentException(Errors.format(
@@ -493,28 +498,22 @@ public final class Units extends Static
* and some frequently-used units. The list of recognized units may be updated in any future
* version of SIS.</p>
*
- * <p>The {@link org.apache.sis.referencing.factory.epsg.DirectEpsgFactory} uses this method
+ * <p>The {@link org.apache.sis.referencing.factory.sql.EPSGDataAccess} class uses this method
* for fetching the base units, and derives automatically other units from the information
* found in the EPSG database. This method is also used by other classes not directly related
- * to the EPSG database, like {@link org.apache.sis.referencing.factory.web.AutoCRSFactory}
+ * to the EPSG database, like {@link org.apache.sis.referencing.factory.CommonAuthorityFactory}
* which uses EPSG code for identifying units.</p>
*
* <p>The currently recognized values are:</p>
* <table class="sis">
* <caption>EPSG codes for units</caption>
* <tr>
- * <th>Linear units</th>
- * <th class="sep">Angular units</th>
+ * <th>Angular units</th>
+ * <th class="sep">Linear units</th>
+ * <th class="sep">Temporal units</th>
* <th class="sep">Scale units</th>
* </tr><tr>
- * <td><table class="compact" summary="Linear units">
- * <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
- * <tr><td>9001</td><td>metre</td></tr>
- * <tr><td>9002</td><td>foot</td></tr>
- * <tr><td>9030</td><td>nautical mile</td></tr>
- * <tr><td>9036</td><td>kilometre</td></tr>
- * </table></td>
- * <td class="sep"><table class="compact" summary="Angular units">
+ * <td><table class="compact" summary="Angular units">
* <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
* <tr><td>9101</td><td>radian</td></tr>
* <tr><td>9102</td><td>decimal degree</td></tr>
@@ -528,6 +527,18 @@ public final class Units extends Static
* <tr><td>9111</td><td>sexagesimal degree-minute</td></tr>
* <tr><td>9122</td><td>decimal degree</td></tr>
* </table></td>
+ * <td class="sep"><table class="compact" summary="Linear units">
+ * <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
+ * <tr><td>9001</td><td>metre</td></tr>
+ * <tr><td>9002</td><td>foot</td></tr>
+ * <tr><td>9030</td><td>nautical mile</td></tr>
+ * <tr><td>9036</td><td>kilometre</td></tr>
+ * </table></td>
+ * <td class="sep"><table class="compact" summary="Time units">
+ * <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
+ * <tr><td>1029</td><td>year</td></tr>
+ * <tr><td>1040</td><td>second</td></tr>
+ * </table></td>
* <td class="sep"><table class="compact" summary="Scale units">
* <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
* <tr><td>9201</td><td>one</td></tr>
@@ -544,9 +555,13 @@ public final class Units extends Static
*
* @param code The EPSG code for a unit of measurement.
* @return The unit, or {@code null} if the code is unrecognized.
+ *
+ * @see org.apache.sis.referencing.factory.GeodeticAuthorityFactory#createUnit(String)
*/
public static Unit<?> valueOfEPSG(final int code) {
switch (code) {
+ case 1029: return YEAR;
+ case 1040: return SI .SECOND;
case 9001: return SI .METRE;
case 9002: return NonSI.FOOT;
case 9030: return NonSI.NAUTICAL_MILE;
@@ -575,8 +590,8 @@ public final class Units extends Static
*
* <p>The same unit may be represented by different EPSG codes depending on the context:</p>
* <ul>
- * <li>EPSG:9102 – <cite>degree</cite> – is used for prime meridian and coordinate operation parameters.</li>
- * <li>EPSG:9122 – <cite>degree (supplier to define representation)</cite> – is used for coordinate system axes.</li>
+ * <li>EPSG::9102 – <cite>degree</cite> – is used for prime meridian and coordinate operation parameters.</li>
+ * <li>EPSG::9122 – <cite>degree (supplier to define representation)</cite> – is used for coordinate system axes.</li>
* </ul>
*
* When such choice exists, the code to return is determined by the {@code inAxis} argument,
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -30,6 +30,7 @@ import java.util.MissingResourceExceptio
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
+import java.util.logging.Level;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
@@ -42,17 +43,23 @@ import org.apache.sis.util.CharSequences
import org.apache.sis.util.Version;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.logging.LoggerFactory;
+import org.apache.sis.util.resources.Messages;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.collection.TreeTable;
import org.apache.sis.util.collection.TreeTables;
import org.apache.sis.util.collection.DefaultTreeTable;
import org.apache.sis.internal.system.Loggers;
import org.apache.sis.internal.system.Modules;
+import org.apache.sis.internal.system.Shutdown;
+import org.apache.sis.internal.system.DataDirectory;
import static java.lang.System.getProperty;
import static org.apache.sis.util.collection.TableColumn.NAME;
import static org.apache.sis.util.collection.TableColumn.VALUE_AS_TEXT;
+// Branch-dependent imports
+import java.nio.file.Path;
+
/**
* Provides information about the Apache SIS running environment.
@@ -71,7 +78,7 @@ import static org.apache.sis.util.collec
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.7
* @module
*/
public enum About {
@@ -112,6 +119,8 @@ public enum About {
* <ul>
* <li>User directory</li>
* <li>Default directory</li>
+ * <li>SIS data directory</li>
+ * <li>Temporary directory</li>
* <li>Java home directory</li>
* </ul>
*/
@@ -189,10 +198,10 @@ public enum About {
TreeTable.Node section = null;
About newSection = VERSIONS;
fill: for (int i=0; ; i++) {
- short nameKey = 0; // The Vocabulary.Key for 'name', used only if name is null.
- String name = null; // The value to put in the 'Name' column of the table.
- Object value = null; // The value to put in the 'Value' column of the table.
- String[] children = null; // Optional children to write below the node.
+ short nameKey = 0; // The Vocabulary.Key for 'name', used only if name is null.
+ String name = null; // The value to put in the 'Name' column of the table.
+ Object value = null; // The value to put in the 'Value' column of the table.
+ String[] children = null; // Optional children to write below the node.
switch (i) {
case 0: {
if (sections.contains(VERSIONS)) {
@@ -217,6 +226,13 @@ fill: for (int i=0; ; i++) {
break;
}
case 3: {
+ if (sections.contains(VERSIONS)) {
+ nameKey = Vocabulary.Keys.Container;
+ value = Shutdown.getContainer(); // Sometime contains version information.
+ }
+ break;
+ }
+ case 4: {
newSection = LOCALIZATION;
if (sections.contains(LOCALIZATION)) {
final Locale current = Locale.getDefault();
@@ -231,7 +247,7 @@ fill: for (int i=0; ; i++) {
}
break;
}
- case 4: {
+ case 5: {
if (sections.contains(LOCALIZATION)) {
final TimeZone current = TimeZone.getDefault();
if (current != null) {
@@ -252,7 +268,7 @@ fill: for (int i=0; ; i++) {
}
break;
}
- case 5: {
+ case 6: {
if (sections.contains(LOCALIZATION)) {
nameKey = Vocabulary.Keys.CurrentDateTime;
final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, formatLocale);
@@ -263,7 +279,7 @@ fill: for (int i=0; ; i++) {
}
break;
}
- case 6: {
+ case 7: {
if (sections.contains(LOCALIZATION)) {
final Charset current = Charset.defaultCharset();
if (current != null) {
@@ -283,7 +299,7 @@ fill: for (int i=0; ; i++) {
}
break;
}
- case 7: {
+ case 8: {
newSection = LOGGING;
if (sections.contains(LOGGING)) {
nameKey = Vocabulary.Keys.Implementation;
@@ -292,7 +308,24 @@ fill: for (int i=0; ; i++) {
}
break;
}
- case 8: {
+ case 9: {
+ if (sections.contains(LOGGING)) {
+ nameKey = Vocabulary.Keys.Level;
+ final Level level = Logging.getLogger("").getLevel(); // Root logger level.
+ value = level.getLocalizedName();
+ final Map<String,Level> levels = Loggers.getEffectiveLevels();
+ if (levels.size() != 1 || !level.equals(levels.get(Loggers.ROOT))) {
+ int j = 0;
+ children = new String[levels.size() * 2];
+ for (final Map.Entry<String,Level> entry : levels.entrySet()) {
+ children[j++] = entry.getKey();
+ children[j++] = entry.getValue().getLocalizedName();
+ }
+ }
+ }
+ break;
+ }
+ case 10: {
newSection = PATHS;
if (sections.contains(PATHS)) {
nameKey = Vocabulary.Keys.UserHome;
@@ -300,28 +333,45 @@ fill: for (int i=0; ; i++) {
}
break;
}
- case 9: {
+ case 11: {
if (sections.contains(PATHS)) {
nameKey = Vocabulary.Keys.CurrentDirectory;
value = getProperty("user.dir");
}
break;
}
- case 10: {
+ case 12: {
+ if (sections.contains(PATHS)) {
+ nameKey = Vocabulary.Keys.DataDirectory;
+ value = System.getenv(DataDirectory.ENV);
+ if (value == null) {
+ value = Messages.getResources(locale).getString(Messages.Keys.DataDirectoryNotSpecified_1, DataDirectory.ENV);
+ } else {
+ final Path path = DataDirectory.getRootDirectory();
+ if (path != null) {
+ value = path.toString();
+ } else {
+ value = value + " (" + resources.getString(Vocabulary.Keys.Invalid) + ')';
+ }
+ }
+ }
+ break;
+ }
+ case 13: {
if (sections.contains(PATHS)) {
nameKey = Vocabulary.Keys.TemporaryFiles;
value = getProperty("java.io.tmpdir");
}
break;
}
- case 11: {
+ case 14: {
if (sections.contains(PATHS)) {
nameKey = Vocabulary.Keys.JavaHome;
value = javaHome = getProperty("java.home");
}
break;
}
- case 12: {
+ case 15: {
newSection = LIBRARIES;
if (sections.contains(LIBRARIES)) {
nameKey = Vocabulary.Keys.JavaExtensions;
@@ -329,7 +379,7 @@ fill: for (int i=0; ; i++) {
}
break;
}
- case 13: {
+ case 16: {
if (sections.contains(LIBRARIES)) {
nameKey = Vocabulary.Keys.Classpath;
value = classpath(getProperty("java.class.path"), false);
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -73,7 +73,7 @@ import static java.lang.Character.*;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.4
+ * @version 0.7
* @module
*
* @see StringBuilders
@@ -396,7 +396,7 @@ search: for (; fromIndex <= toIndex;
}
char head = (char) toSearch;
char tail = (char) 0;
- if (head != toSearch) { // Outside BMP plane?
+ if (head != toSearch) { // Outside BMP plane?
head = highSurrogate(toSearch);
tail = lowSurrogate (toSearch);
toIndex--;
@@ -1323,12 +1323,13 @@ searchWordBreak: while (true) {
}
/**
- * Creates an acronym from the given text. If every characters in the given text are upper
- * case, then the text is returned unchanged on the assumption that it is already an acronym.
- * Otherwise this method returns a string containing the first character of each word, where
- * the words are separated by the camel case convention, the {@code '_'} character, or any
- * character which is not a {@linkplain Character#isUnicodeIdentifierPart(int) Unicode
- * identifier part} (including spaces).
+ * Creates an acronym from the given text. This method returns a string containing the first character of each word,
+ * where the words are separated by the camel case convention, the {@code '_'} character, or any character which is
+ * not a {@linkplain Character#isUnicodeIdentifierPart(int) Unicode identifier part} (including spaces).
+ *
+ * <p>An exception to the above rule happens if the given text is a Unicode identifier without the {@code '_'}
+ * character, and every characters are upper case. In such case the text is returned unchanged on the assumption
+ * that it is already an acronym.</p>
*
* <p><b>Examples:</b> given {@code "northEast"}, this method returns {@code "NE"}.
* Given {@code "Open Geospatial Consortium"}, this method returns {@code "OGC"}.</p>
@@ -1338,9 +1339,9 @@ searchWordBreak: while (true) {
*/
public static CharSequence camelCaseToAcronym(CharSequence text) {
text = trimWhitespaces(text);
- if (text != null && !isUpperCase(text, 0, text.length())) {
+ if (text != null && !isAcronym(text)) {
final int length = text.length();
- final StringBuilder buffer = new StringBuilder(8); // Acronyms are usually short.
+ final StringBuilder buffer = new StringBuilder(8); // Acronyms are usually short.
boolean wantChar = true;
for (int i=0; i<length;) {
final int c = codePointAt(text, i);
@@ -1367,7 +1368,7 @@ searchWordBreak: while (true) {
* first one is upper-case as well. This is for handling the identifiers which
* are compliant to Java-Beans convention (e.g. "northEast").
*/
- if (isUpperCase(buffer, 1, acrlg)) {
+ if (isUpperCase(buffer, 1, acrlg, true)) {
final int c = buffer.codePointAt(0);
final int up = toUpperCase(c);
if (c != up) {
@@ -1494,6 +1495,16 @@ cmp: while (ia < lga) {
}
/**
+ * Returns {@code true} if the given text is presumed to be an acronym. Acronyms are presumed
+ * to be valid Unicode identifiers in all upper-case letters and without the {@code '_'} character.
+ *
+ * @see #camelCaseToAcronym(CharSequence)
+ */
+ private static boolean isAcronym(final CharSequence text) {
+ return isUpperCase(text) && indexOf(text, '_', 0, text.length()) < 0 && isUnicodeIdentifier(text);
+ }
+
+ /**
* Returns {@code true} if the given identifier is a legal Unicode identifier.
* This method returns {@code true} if the identifier length is greater than zero,
* the first character is a {@linkplain Character#isUnicodeIdentifierStart(int)
@@ -1556,27 +1567,43 @@ cmp: while (ia < lga) {
}
/**
- * Returns {@code true} if every characters in the given sequence are
- * {@linkplain Character#isUpperCase(int) upper-case} letters.
- *
- * <div class="note"><b>Note:</b>
- * The behavior of this method regarding digits and punctuation is unspecified
- * and may change in future versions.</div>
+ * Returns {@code true} if the given text is non-null, contains at least one upper-case character and
+ * no lower-case character. Space and punctuation are ignored.
*
- * @param text The character sequence to test.
- * @return {@code true} if every character are upper-case.
+ * @param text The character sequence to test (may be {@code null}).
+ * @return {@code true} if non-null, contains at least one upper-case character and no lower-case character.
*
* @see String#toUpperCase()
+ *
+ * @since 0.7
*/
- static boolean isUpperCase(final CharSequence text, int lower, final int upper) {
+ public static boolean isUpperCase(final CharSequence text) {
+ return isUpperCase(text, 0, length(text), false);
+ }
+
+ /**
+ * Returns {@code true} if the given sub-sequence is non-null, contains at least one upper-case character and
+ * no lower-case character. Space and punctuation are ignored.
+ *
+ * @param text The character sequence to test.
+ * @param lower Index of the first character to check, inclusive.
+ * @param upper Index of the last character to check, exclusive.
+ * @param hasUpperCase {@code true} if this method should behave as if the given text already had
+ * at least one upper-case character (not necessarily in the portion given by the indices).
+ * @return {@code true} if contains at least one upper-case character and no lower-case character.
+ */
+ private static boolean isUpperCase(final CharSequence text, int lower, final int upper, boolean hasUpperCase) {
while (lower < upper) {
final int c = codePointAt(text, lower);
- if (!Character.isUpperCase(c)) {
+ if (Character.isLowerCase(c)) {
return false;
}
+ if (!hasUpperCase) {
+ hasUpperCase = Character.isUpperCase(c);
+ }
lower += charCount(c);
}
- return true;
+ return hasUpperCase;
}
/**
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -31,6 +31,7 @@ package org.apache.sis.util;
* <li>{@link #IGNORE_METADATA} – Only the attributes relevant to the object functionality are compared.</li>
* <li>{@link #APPROXIMATIVE} – Only the attributes relevant to the object functionality are compared,
* with some tolerance threshold on numerical values.</li>
+ * <li>{@link #ALLOW_VARIANT} – For objects not really equal but related (e.g. CRS using different axis order).</li>
* <li>{@link #DEBUG} – Special mode for figuring out why two objects expected to be equal are not.</li>
* </ol>
*
@@ -41,7 +42,7 @@ package org.apache.sis.util;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.6
+ * @version 0.7
* @module
*
* @see LenientComparable#equals(Object, ComparisonMode)
@@ -69,9 +70,8 @@ public enum ComparisonMode {
STRICT,
/**
- * Only the attributes published in some contract (typically a GeoAPI interface) need
- * to be compared. The implementation classes do not need to be the same and some private
- * attributes may be ignored.
+ * Only the attributes published in some contract (typically a GeoAPI interface) need to be compared.
+ * The implementation classes do not need to be the same and some private attributes may be ignored.
*
* <p>Note that this comparison mode does <strong>not</strong> guaranteed {@link Object#hashCode()}
* consistency, neither comparison symmetry (i.e. {@code A.equals(B)} and {@code B.equals(A)} may
@@ -93,25 +93,24 @@ public enum ComparisonMode {
* are only informative can be ignored. This comparison mode is typically less strict than
* {@link #BY_CONTRACT}.
*
- * <div class="section">Examples</div>
- * If the objects being compared are
- * {@link org.opengis.referencing.crs.CoordinateReferenceSystem} instances, then only the
- * properties relevant to the coordinate localization shall be compared. Metadata like the
- * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem#getIdentifiers() identifiers}
- * or the {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem#getDomainOfValidity()
- * domain of validity}, which have no impact on the coordinates being calculated, shall be ignored.
- *
- * <p>If the objects being compared are {@link org.opengis.referencing.operation.MathTransform}
- * instances, then two transforms defined in a different way may be considered equivalent.
- * For example it is possible to define a
- * {@linkplain org.apache.sis.referencing.operation.projection.Mercator Mercator} projection
- * in two different ways, as a {@code "Mercator (1SP)"} or a {@code "Mercator (2SP)"} projection,
- * each having their own set of parameters. The {@link #STRICT} or {@link #BY_CONTRACT} modes
- * shall consider two projections as equal only if their
+ * <div class="section">Application to coordinate reference systems</div>
+ * If the objects being compared are {@link org.opengis.referencing.crs.CoordinateReferenceSystem} instances,
+ * then only the properties relevant to the coordinate localization shall be compared.
+ * Metadata like the {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getIdentifiers() identifiers}
+ * or the {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getDomainOfValidity() domain of validity},
+ * which have no impact on the coordinates being calculated, shall be ignored.
+ *
+ * <div class="section">Application to coordinate operations</div>
+ * If the objects being compared are {@link org.opengis.referencing.operation.MathTransform} instances,
+ * then two transforms defined in a different way may be considered equivalent. For example it is possible
+ * to define a {@linkplain org.apache.sis.referencing.operation.projection.Mercator Mercator} projection in
+ * two different ways, as a <cite>"Mercator (1SP)"</cite> or as a <cite>"Mercator (2SP)"</cite> projection,
+ * each having their own set of parameters.
+ * The {@link #STRICT} or {@link #BY_CONTRACT} modes shall consider two projections as equal only if their
* {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform#getParameterValues()
* parameter values} are strictly identical, while the {@code IGNORE_METADATA} mode can consider
* those objects as equivalent despite difference in the set of parameters, as long as coordinate
- * transformations still produce the same results.</p>
+ * transformations still produce the same results.
*
* <div class="note"><b>Example:</b> A <cite>"Mercator (2SP)"</cite> projection with a <cite>standard parallel</cite>
* value of 60° produces the same results than a <cite>"Mercator (1SP)"</cite> projection with a <cite>scale factor</cite>
@@ -125,17 +124,37 @@ public enum ComparisonMode {
* Only the attributes relevant to the object functionality are compared, with some tolerance
* threshold on numerical values.
*
- * <div class="section">Application to coordinate transforms</div>
- * If two {@link org.opengis.referencing.operation.MathTransform} objects are considered equal
- * according this mode, then for any given identical source position, the two compared transforms
- * shall compute at least approximatively the same target position. A small difference is
- * tolerated between the target coordinates calculated by the two math transforms. How small
- * is "small" is implementation dependent - the threshold can not be specified in the current
+ * <div class="section">Application to coordinate operations</div>
+ * If two {@link org.opengis.referencing.operation.MathTransform} objects are considered equal according this mode,
+ * then for any given identical source position, the two compared transforms shall compute at least approximatively
+ * the same target position.
+ * A small difference is tolerated between the target coordinates calculated by the two math transforms.
+ * How small is “small” is implementation dependent — the threshold can not be specified in the current
* implementation, because of the non-linear nature of map projections.
*/
APPROXIMATIVE,
/**
+ * Most but not all attributes relevant to the object functionality are compared.
+ * This comparison mode is equivalent to {@link #APPROXIMATIVE}, except that it
+ * ignores some attributes that may differ between objects not equal but related.
+ *
+ * <p>The main purpose of this method is to verify if two Coordinate Reference Systems (CRS)
+ * are approximatively equal ignoring axis order.</p>
+ *
+ * <div class="note"><b>Example:</b>
+ * consider two geographic coordinate reference systems with the same attributes except axis order,
+ * where one CRS uses (<var>latitude</var>, <var>longitude</var>) axes
+ * and the other CRS uses (<var>longitude</var>, <var>latitude</var>) axes.
+ * All comparison modes (even {@code APPROXIMATIVE}) will consider those two CRS as different,
+ * except this {@code ALLOW_VARIANT} mode which will consider one CRS to be a variant of the other.
+ * </div>
+ *
+ * @since 0.7
+ */
+ ALLOW_VARIANT,
+
+ /**
* Same as {@link #APPROXIMATIVE}, except that an {@link AssertionError} is thrown if the two
* objects are not equal and assertions are enabled. The exception message and stack trace help
* to locate which attributes are not equal. This mode is typically used in assertions like below:
@@ -178,14 +197,15 @@ public enum ComparisonMode {
}
/**
- * If the two given objects are equals according one of the modes enumerated in this class,
- * then returns that mode. Otherwise returns {@code null}. This method is used mostly for
- * diagnostic purpose.
+ * If the two given objects are equal according one of the modes enumerated in this class,
+ * then returns that mode. Otherwise returns {@code null}.
+ *
+ * <p><b>Note:</b> this method never return the {@link #DEBUG} mode.</p>
*
* @param o1 The first object to compare, or {@code null}.
* @param o2 The second object to compare, or {@code null}.
- * @return The must suitable comparison mode, or {@code null} if the two given objects
- * are not equal for any mode in this enumeration.
+ * @return The most suitable comparison mode, or {@code null} if the two given objects
+ * are not equal according any mode in this enumeration.
*/
public static ComparisonMode equalityLevel(final Object o1, Object o2) {
if (o1 == o2) {
@@ -207,6 +227,7 @@ public enum ComparisonMode {
if (cp.equals(o2, BY_CONTRACT)) return BY_CONTRACT;
if (cp.equals(o2, IGNORE_METADATA)) return IGNORE_METADATA;
if (cp.equals(o2, APPROXIMATIVE)) return APPROXIMATIVE;
+ if (cp.equals(o2, ALLOW_VARIANT)) return ALLOW_VARIANT;
}
return null;
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Disposable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Disposable.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Disposable.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Disposable.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -18,18 +18,31 @@ package org.apache.sis.util;
/**
- * A resource that can be disposed when waiting for the garbage collector would be overly
- * conservative. Invoking the {@link #dispose()} method allows any resources held by this
- * object to be released. The result of calling any other method subsequent to a call to
- * this method is undefined.
+ * A resource that can be disposed when waiting for the garbage collector would be overly conservative.
+ * Invoking the {@link #dispose()} method allows any resources held by this object to be released.
+ * The result of calling any other method subsequent to a call to this method is undefined.
+ *
+ * <p>Data integrity shall not depend on {@code dispose()} method invocation.
+ * If some data may need to be {@linkplain java.io.OutputStream#flush() flushed to a stream}
+ * or {@linkplain java.sql.Connection#commit() committed to a database},
+ * then a {@code close()} method should be used instead.</p>
*
* <div class="section">Relationship with {@code Closeable}</div>
- * Some SIS classes may implement both the {@code Disposeable} and {@link java.io.Closeable}
- * interfaces. While very similar, those two interfaces serve slightly different purposes.
- * The {@code Closeable} interface closes a stream or a connection, but some classes can be
- * reused with a different stream. For example an {@link javax.imageio.ImageReader} can be
- * instantiated once and reused many time for reading different image streams of the same
- * format. However once an object has been disposed, it can not be used anymore.
+ * Some classes may implement both the {@code Disposeable} and {@link java.io.Closeable} interfaces.
+ * While very similar, those two interfaces serve slightly different purposes. The {@code Closeable}
+ * interface closes a stream or a connection, but some classes allow the object to be reused with a
+ * different stream. However once an object has been disposed, it can not be used anymore.
+ *
+ * <div class="note"><b>Example:</b>
+ * {@link javax.imageio.ImageReader} and {@link javax.imageio.ImageWriter} allow to reuse the same instance
+ * many times for reading or writing different images in the same format. New streams can be created, given
+ * to the {@code ImageReader} or {@code ImageWriter} and closed many times as long as {@code dispose()} has
+ * not been invoked.</div>
+ *
+ * Another difference is that {@link #dispose()} does not throw any checked exception.
+ * That method may be invoked in a background thread performing cleanup tasks,
+ * which would not know what to do in case of failure.
+ * Error during {@code dispose()} execution should not result in any lost of data.
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Localized.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Localized.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Localized.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Localized.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -35,7 +35,7 @@ public interface Localized {
* implementation-dependent, but typical interpretations are:
*
* <ul>
- * <li>A synonymous of the {@linkplain Locale#getDefault() system default locale};</li>
+ * <li>A synonymous of the {@linkplain Locale#getDefault() system default locale}.</li>
* <li>A synonymous of {@link Locale#ROOT} for an "unlocalized" service. For example the
* service may format numbers using {@link Double#toString(double)} instead than
* {@link java.text.NumberFormat}.</li>
@@ -45,8 +45,6 @@ public interface Localized {
* Nevertheless client codes should be prepared to receive null values.
*
* @return The locale, or {@code null} if not explicitly defined.
- *
- * @see org.apache.sis.io.CompoundFormat#getLocale()
*/
Locale getLocale();
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -32,10 +32,9 @@ import org.apache.sis.util.Disposable;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.system.DelayedRunnable;
+import org.apache.sis.internal.system.DelayedExecutor;
import org.apache.sis.internal.system.ReferenceQueueConsumer;
-import static org.apache.sis.internal.system.DelayedExecutor.executeDaemonTask;
-
// Branch-dependent imports
import org.apache.sis.internal.jdk8.Supplier;
@@ -304,7 +303,7 @@ public class Cache<K,V> extends Abstract
final Object previous;
if (value != null) {
previous = map.put(key, value);
- executeDaemonTask(new Strong(key, value));
+ DelayedExecutor.schedule(new Strong(key, value));
} else {
previous = map.remove(key);
}
@@ -383,8 +382,8 @@ public class Cache<K,V> extends Abstract
final Reference<V> ref = (Reference<V>) value;
final V result = ref.get();
if (result != null && map.replace(key, ref, result)) {
- ref.clear(); // Prevents the reference from being enqueued.
- executeDaemonTask(new Strong(key, result));
+ ref.clear(); // Prevents the reference from being enqueued.
+ DelayedExecutor.schedule(new Strong(key, result));
}
return result;
}
@@ -476,8 +475,8 @@ public class Cache<K,V> extends Abstract
* would be useless.
*/
if (map.replace(key, ref, result)) {
- ref.clear(); // Prevents the reference from being enqueued.
- executeDaemonTask(new Strong(key, result));
+ ref.clear(); // Prevents the reference from being enqueued.
+ DelayedExecutor.schedule(new Strong(key, result));
}
return new Simple<>(result);
}
@@ -710,7 +709,7 @@ public class Cache<K,V> extends Abstract
lock.unlock();
}
if (done) {
- executeDaemonTask(this);
+ DelayedExecutor.schedule(this);
}
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -45,9 +45,9 @@ import java.util.Objects;
*
* {@preformat java
* public class CityLocation {
- * public static final TableColumn<String> CITY_NAME = new TableColumn<>(String.class);
- * public static final TableColumn<Float> LATITUDE = new TableColumn<>(Float .class);
- * public static final TableColumn<Float> LONGTITUDE = new TableColumn<>(Float .class);
+ * public static final TableColumn<String> CITY_NAME = new TableColumn<>(String.class, "City name");
+ * public static final TableColumn<Float> LATITUDE = new TableColumn<>(Float.class, "Latitude");
+ * public static final TableColumn<Float> LONGTITUDE = new TableColumn<>(Float.class, "Longitude");
*
* public TreeTable createTable() {
* DefaultTreeTable table = new DefaultTreeTable(CITY_NAME, LATITUDE, LONGITUDE);
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java?rev=1723780&r1=1723779&r2=1723780&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] Fri Jan 8 18:29:04 2016
@@ -30,6 +30,9 @@ import java.text.ParsePosition;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.nio.charset.Charset;
+import org.opengis.util.Type;
+import org.opengis.util.Record;
+import org.opengis.util.GenericName;
import org.opengis.util.ControlledVocabulary;
import org.opengis.util.InternationalString;
import org.apache.sis.io.LineAppender;
@@ -95,7 +98,7 @@ import static org.apache.sis.util.Charac
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.3
- * @version 0.5
+ * @version 0.7
* @module
*/
public class TreeTableFormat extends TabularFormat<TreeTable> {
@@ -596,6 +599,12 @@ public class TreeTableFormat extends Tab
private final Map<Object,Object> parentObjects;
/**
+ * The format for the column in process of being written. This is a format to use for the column as a whole.
+ * This field is updated for every new column to write. May be {@code null} if the format is unspecified.
+ */
+ private transient Format columnFormat;
+
+ /**
* Creates a new instance which will write to the given appendable.
*
* @param out Where to format the tree.
@@ -614,21 +623,42 @@ public class TreeTableFormat extends Tab
}
/**
+ * Localizes the given name in the display locale, or returns "(Unnamed)" if no localized value is found.
+ */
+ private String toString(final GenericName name) {
+ final Locale locale = getDisplayLocale();
+ if (name != null) {
+ final InternationalString i18n = name.toInternationalString();
+ if (i18n != null) {
+ final String localized = i18n.toString(locale);
+ if (localized != null) {
+ return localized;
+ }
+ }
+ final String localized = name.toString();
+ if (localized != null) {
+ return localized;
+ }
+ }
+ return '(' + Vocabulary.getResources(locale).getString(Vocabulary.Keys.Unnamed) + ')';
+ }
+
+ /**
* Appends a textual representation of the given value.
*
- * @param format The format to use for the column as a whole, or {@code null} if unknown.
- * @param value The value to format (may be {@code null}).
+ * @param value The value to format (may be {@code null}).
+ * @param recursive {@code true} if this method is invoking itself for writing collection values.
*/
- private void formatValue(Format format, final Object value) throws IOException {
+ private void formatValue(final Object value, final boolean recursive) throws IOException {
final CharSequence text;
if (value == null) {
text = " "; // String for missing value.
- } else if (format != null) {
- if (format instanceof CompoundFormat<?>) {
- formatValue((CompoundFormat<?>) format, value);
+ } else if (columnFormat != null) {
+ if (columnFormat instanceof CompoundFormat<?>) {
+ formatValue((CompoundFormat<?>) columnFormat, value);
return;
}
- text = format.format(value);
+ text = columnFormat.format(value);
} else if (value instanceof InternationalString) {
text = ((InternationalString) value).toString(getDisplayLocale());
} else if (value instanceof CharSequence) {
@@ -637,6 +667,8 @@ public class TreeTableFormat extends Tab
text = Types.getCodeTitle((ControlledVocabulary) value).toString(getDisplayLocale());
} else if (value instanceof Enum<?>) {
text = CharSequences.upperCaseToSentence(((Enum<?>) value).name());
+ } else if (value instanceof Type) {
+ text = toString(((Type) value).getTypeName());
} else if (value instanceof Locale) {
final Locale locale = getDisplayLocale();
text = (locale != Locale.ROOT) ? ((Locale) value).getDisplayName(locale) : value.toString();
@@ -649,20 +681,55 @@ public class TreeTableFormat extends Tab
} else if (value instanceof Currency) {
final Locale locale = getDisplayLocale();
text = (locale != Locale.ROOT) ? ((Currency) value).getDisplayName(locale) : value.toString();
+ } else if (value instanceof Record) {
+ formatCollection(((Record) value).getAttributes().values(), recursive);
+ return;
+ } else if (value instanceof Iterable<?>) {
+ formatCollection((Iterable<?>) value, recursive);
+ return;
+ } else if (value instanceof Object[]) {
+ formatCollection(Arrays.asList((Object[]) value), recursive);
+ return;
} else {
/*
- * Check for a value-by-value format only as last resort.
- * If a column-wide format was given in argument to this method,
- * that format should have been used by above code in order to
- * produce a more uniform formatting.
+ * Check for a value-by-value format only as last resort. If a column-wide format was specified by
+ * the 'columnFormat' field, that format should have been used by above code in order to produce a
+ * more uniform formatting.
*/
- format = getFormat(value.getClass());
+ final Format format = getFormat(value.getClass());
text = (format != null) ? format.format(value) : value.toString();
}
append(text);
}
/**
+ * Writes the values of the given collection. A maximum of 10 values will be written.
+ * If the collection contains other collections, the other collections will <strong>not</strong>
+ * be written recursively.
+ */
+ private void formatCollection(final Iterable<?> values, final boolean recursive)
+ throws IOException
+ {
+ if (values != null) {
+ if (recursive) {
+ append('…'); // Do not format collections inside collections.
+ } else {
+ int count = 0;
+ for (final Object value : values) {
+ if (value != null) {
+ if (count != 0) append(", ");
+ formatValue(value, true);
+ if (++count == 10) { // Arbitrary limit.
+ append(", …");
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Work around for the inability to define the variable {@code <V>} locally.
*/
@Workaround(library="JDK", version="1.7")
@@ -694,7 +761,8 @@ public class TreeTableFormat extends Tab
if (i != 0) {
writeColumnSeparator(out);
}
- formatValue(formats[i], values[i]);
+ columnFormat = formats[i];
+ formatValue(values[i], false);
clear();
}
out.append(lineSeparator);