Author: desruisseaux
Date: Mon Jun 6 23:33:04 2016
New Revision: 1747091
URL: http://svn.apache.org/viewvc?rev=1747091&view=rev
Log:
Partial port (still incomplete) of referencing services as Apache OpenOffice addins.
This provide some of the services provided by the command-line tools, but available as formulas in Calc.
Added:
sis/branches/JDK8/application/sis-openoffice/ (with props)
sis/branches/JDK8/application/sis-openoffice/pom.xml (with props)
sis/branches/JDK8/application/sis-openoffice/src/
sis/branches/JDK8/application/sis-openoffice/src/main/
sis/branches/JDK8/application/sis-openoffice/src/main/java/
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/AnglePattern.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CacheKey.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CalcAddins.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CodeType.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/MethodInfo.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Referencing.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.idl (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/package-info.java (with props)
sis/branches/JDK8/application/sis-openoffice/src/main/unopkg/
sis/branches/JDK8/application/sis-openoffice/src/main/unopkg/build-instruction.html (with props)
sis/branches/JDK8/application/sis-openoffice/src/test/
sis/branches/JDK8/application/sis-openoffice/src/test/java/
Propchange: sis/branches/JDK8/application/sis-openoffice/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Jun 6 23:33:04 2016
@@ -0,0 +1,10 @@
+.project
+.settings
+.classpath
+.jetproperties
+.wtpmodules
+target
+bin
+cobertura.ser
+nbproject
+nbactions.xml
Added: sis/branches/JDK8/application/sis-openoffice/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/pom.xml?rev=1747091&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/pom.xml (added)
+++ sis/branches/JDK8/application/sis-openoffice/pom.xml Mon Jun 6 23:33:04 2016
@@ -0,0 +1,182 @@
+
+
+
+
+
+ 4.0.0
+
+
+ org.apache.sis
+ application
+ 0.8-jdk8-SNAPSHOT
+
+
+
+
+ org.apache.sis.application
+ sis-openoffice
+ jar
+ Bridges to Apache OpenOffice or LibreOffice
+
+
+ Provides some Apache SIS functionalities as Apache OpenOffice addins.
+ For example, addins provide coordinate operation services as formulas
+ inside the Calc spreadsheet.
+
+
+
+
+
+
+ Martin Desruisseaux
+ desruisseaux
+ desruisseaux@apache.org
+ Geomatys
+ http://www.geomatys.com
+ +1
+
+ developer
+
+
+
+
+
+
+ Richard Deplanque
+ Université de Nouvelle-Calédonie
+ +11
+
+ Java Developer
+
+
+
+
+
+
+
+ 3.2.1
+
+
+
+
+ org.opengis
+ geoapi-pending
+
+
+ javax.measure
+ jsr-275
+
+
+ org.apache.sis.core
+ sis-referencing
+ ${project.version}
+
+
+ org.apache.sis.core
+ sis-metadata
+ ${project.version}
+
+
+ org.apache.sis.core
+ sis-utility
+ ${project.version}
+
+
+
+
+ org.openoffice
+ juh
+ ${openoffice.version}
+ provided
+
+
+ org.openoffice
+ jurt
+ ${openoffice.version}
+ provided
+
+
+ org.openoffice
+ ridl
+ ${openoffice.version}
+ provided
+
+
+ org.openoffice
+ unoil
+ ${openoffice.version}
+ provided
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+
+ org.apache.sis.openoffice.Registration
+
+
+
+
+
+
+
+
+ org.apache.sis.core
+ sis-build-helper
+ ${project.version}
+
+ sis-${project.version}
+ true
+
+
+
+
+ javamaker
+ unopkg
+
+
+
+
+
+
+
Propchange: sis/branches/JDK8/application/sis-openoffice/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/application/sis-openoffice/pom.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Added: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/AnglePattern.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/AnglePattern.java?rev=1747091&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/AnglePattern.java (added)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/AnglePattern.java [UTF-8] Mon Jun 6 23:33:04 2016
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.openoffice;
+
+import java.util.Locale;
+import java.text.ParseException;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.lang.IllegalArgumentException;
+import org.apache.sis.measure.Angle;
+import org.apache.sis.measure.AngleFormat;
+import org.apache.sis.measure.Latitude;
+import org.apache.sis.measure.Longitude;
+import org.apache.sis.util.collection.Cache;
+
+
+/**
+ * The pattern for parsing and formatting angle values.
+ * The expected pattern is as described by {@link AngleFormat} with the following extension:
+ *
+ *
+ * - If the pattern ends with E or W, then the angle is formatted as a longitude.
+ * - If the pattern ends with N or S, then the angle is formatted as a latitude.
+ *
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.8
+ * @version 0.8
+ * @module
+ */
+final class AnglePattern {
+ /**
+ * Enumeration of possible {@link #type} values.
+ */
+ private static final byte LATITUDE = 1, LONGITUDE = 2;
+
+ /**
+ * A pattern to be given to {@link AngleFormat} constructor.
+ */
+ private String pattern;
+
+ /**
+ * {@value #LATITUDE} for latitude, {@value #LONGITUDE} for longitude, or 0 otherwise.
+ */
+ private byte type;
+
+ /**
+ * Converts the given argument to a pattern valid for {@link AngleFormat}.
+ *
+ * @param patternOrVoid the optional pattern argument from the OpenOffice formula.
+ * @throws IllegalArgumentException if {@code patternOrVoid} is not a string value or void.
+ */
+ AnglePattern(final Object patternOrVoid) throws IllegalArgumentException {
+ if (AnyConverter.isVoid(patternOrVoid)) {
+ pattern = "D°MM'SS.s\"";
+ } else {
+ pattern = AnyConverter.toString(patternOrVoid);
+ final int lc = pattern.length() - 1;
+ if (lc > 0) {
+ final char c = pattern.charAt(lc);
+ switch (c) {
+ case 'N': case 'n': case 'S': case 's': type = LATITUDE; break;
+ case 'E': case 'e': case 'W': case 'w': type = LONGITUDE; break;
+ default: return;
+ }
+ pattern = pattern.substring(0, lc);
+ }
+ }
+ }
+
+ /**
+ * Returns the angle format to use for this pattern. The formatter is cached on the assumption
+ * that the same pattern will be used for formatting more than once.
+ *
+ * @param locale the locale.
+ * @return the angle format for this pattern and the given locale.
+ */
+ private AngleFormat getAngleFormat(final Locale locale) {
+ final CacheKey key = new CacheKey<>(AngleFormat.class, pattern, locale, null);
+ AngleFormat format = key.peek();
+ if (format == null) {
+ final Cache.Handler handler = key.lock();
+ try {
+ format = handler.peek();
+ if (format == null) {
+ format = new AngleFormat(pattern, locale);
+ }
+ } finally {
+ handler.putAndUnlock(format);
+ }
+ }
+ return format;
+ }
+
+ /**
+ * Parses the given angle.
+ *
+ * @param text the angle to parse.
+ * @param locale the expected locale of the text to parse.
+ */
+ double parse(final String text, final Locale locale) throws ParseException {
+ AngleFormat format = getAngleFormat(locale);
+ Angle angle;
+ try {
+ synchronized (format) {
+ angle = format.parse(text);
+ }
+ } catch (ParseException exception) {
+ // Parse failed. Try to parse as an unlocalized string.
+ format = getAngleFormat(Locale.ROOT);
+ try {
+ synchronized (format) {
+ angle = format.parse(text);
+ }
+ } catch (ParseException ignore) {
+ throw exception;
+ }
+ }
+ return angle.degrees();
+ }
+
+ /**
+ * Formats the given angle.
+ *
+ * @param value the value to format.
+ * @param locale the target locale.
+ */
+ String format(final double value, final Locale locale) {
+ final AngleFormat format = getAngleFormat(locale);
+ final Angle angle;
+ switch (type) {
+ default: angle = new Angle (value); break;
+ case LATITUDE: angle = new Latitude (value); break;
+ case LONGITUDE: angle = new Longitude(value); break;
+ }
+ synchronized (format) {
+ return format.format(angle);
+ }
+ }
+}
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/AnglePattern.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/AnglePattern.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CacheKey.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CacheKey.java?rev=1747091&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CacheKey.java (added)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CacheKey.java [UTF-8] Mon Jun 6 23:33:04 2016
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.openoffice;
+
+import java.util.Arrays;
+import org.apache.sis.util.collection.Cache;
+
+// Branch-dependent imports
+import java.util.Objects;
+
+
+/**
+ * Key of cached results.
+ *
+ * @param the type of cached values.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.8
+ * @version 0.8
+ * @module
+ */
+final class CacheKey {
+ /**
+ * The cache shared by all formulas.
+ */
+ private static final Cache, Object> cache = new Cache<>(32, 10, true);
+
+ /**
+ * The type of cached value.
+ */
+ private final Class type;
+
+ /**
+ * The key for fetching a cached value.
+ * This is for example an EPSG code or a format pattern.
+ */
+ private String key;
+
+ /**
+ * Optional object to use in addition of the key, or {@code null} if none.
+ */
+ private Object ext;
+
+ /**
+ * The area of interest, or {@code null} if none or not relevant.
+ */
+ private final double[] area;
+
+ /**
+ * Creates a new key for a value to cache.
+ *
+ * @param type the type of the value to cache.
+ * @param key the key for fetching a cached value. This is for example an EPSG code or a format pattern.
+ * @param ext optional object to use in addition of the key, or {@code null} if none.
+ * @param area the area of interest, or {@code null} if none or not relevant.
+ */
+ CacheKey(final Class type, final String key, final Object ext, final double[] area) {
+ this.type = type;
+ this.key = key.trim();
+ this.ext = ext;
+ this.area = area;
+ }
+
+ /**
+ * Returns the cached value for this key, or {@code null} if none.
+ */
+ final T peek() {
+ return type.cast(cache.peek(this));
+ }
+
+ /**
+ * Notifies the cache that a value will be computed for this key.
+ * This method must be followed by a {@code try} … {@code finally} block as below:
+ *
+ * {@preformat java
+ * T value = key.peek();
+ * if (value == null) {
+ * final Cache.Handler handler = key.lock();
+ * try {
+ * value = handler.peek();
+ * if (value == null) {
+ * value = createMyObject(key);
+ * }
+ * } finally {
+ * handler.putAndUnlock(value);
+ * }
+ * }
+ * }
+ */
+ @SuppressWarnings("unchecked")
+ final Cache.Handler lock() {
+ key = key.intern(); // Because the same authority code is often used many time.
+ if (ext instanceof String) {
+ ext = ((String) ext).intern();
+ }
+ return (Cache.Handler) cache.lock(this);
+ }
+
+ /**
+ * Returns a hash code value for this key.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, key, ext) + Arrays.hashCode(area);
+ }
+
+ /**
+ * Compares the given object with this key for equality.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof CacheKey>) {
+ final CacheKey> that = (CacheKey>) obj;
+ return type.equals(that.type) &&
+ key .equals(that.key) &&
+ Objects.equals(ext, that.ext) &&
+ Arrays.equals(area, that.area);
+ }
+ return false;
+ }
+}
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CacheKey.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CacheKey.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CalcAddins.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CalcAddins.java?rev=1747091&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CalcAddins.java (added)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CalcAddins.java [UTF-8] Mon Jun 6 23:33:04 2016
@@ -0,0 +1,479 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.openoffice;
+
+import java.util.Map;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.TimeZone;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.LogRecord;
+
+import com.sun.star.sheet.XAddIn;
+import com.sun.star.util.Date;
+import com.sun.star.lang.Locale;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.XServiceName;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.lib.uno.helper.WeakBase;
+
+import org.apache.sis.util.Classes;
+import org.apache.sis.util.Exceptions;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.collection.BackingStoreException;
+
+
+/**
+ * Base class for methods to export as formulas in the Apache OpenOffice spread sheet.
+ *
+ * @author Martin Desruisseaux (IRD, Geomatys)
+ * @since 0.8
+ * @version 0.8
+ * @module
+ */
+abstract class CalcAddins extends WeakBase implements XAddIn, XServiceName, XServiceInfo {
+ /**
+ * {@code true} for throwing an exception in case of failure, or {@code false} for returning {@code NaN} instead.
+ * This apply only to numerical computations; formulas returning a text value will returns the exception message
+ * in case of failure.
+ */
+ static final boolean THROW_EXCEPTION = true;
+
+ /**
+ * Factor for conversions of days to milliseconds.
+ * Used for date conversions as in {@link #toDate(XPropertySet, double)}.
+ */
+ static final long DAY_TO_MILLIS = 24*60*60*1000L;
+
+ /**
+ * The name of the provided service.
+ */
+ static final String ADDIN_SERVICE = "com.sun.star.sheet.AddIn";
+
+ /**
+ * Informations about exported methods.
+ * This map shall be populated at construction time and be unmodified after construction.
+ */
+ final Map methods;
+
+ /**
+ * Locale attribute required by {@code com.sun.star.lang.XLocalizable} interface.
+ */
+ private Locale locale;
+
+ /**
+ * The locale as an object from the standard Java SDK.
+ * Will be fetched only when first needed.
+ */
+ private transient java.util.Locale javaLocale;
+
+ /**
+ * The calendar to uses for date conversions. Will be created only when first needed.
+ */
+ private transient Calendar calendar;
+
+ /**
+ * The logger, fetched when first needed.
+ */
+ private static Logger logger;
+
+ /**
+ * Default constructor. Subclass constructors need to add entries in the {@link #methods} map.
+ */
+ CalcAddins() {
+ methods = new HashMap<>();
+ }
+
+ /**
+ * Sets the locale to be used by this object.
+ *
+ * @param locale the new locale.
+ */
+ @Override
+ public final synchronized void setLocale(final Locale locale) {
+ this.locale = locale;
+ javaLocale = null;
+ }
+
+ /**
+ * Returns the current locale used by this instance.
+ *
+ * @return the current locale.
+ */
+ @Override
+ public final synchronized Locale getLocale() {
+ return locale;
+ }
+
+ /**
+ * Returns the locale as an object from the Java standard SDK.
+ *
+ * @return the current locale.
+ */
+ protected final synchronized java.util.Locale getJavaLocale() {
+ if (javaLocale == null) {
+ if (locale != null) {
+ String language = locale.Language; if (language == null) language = "";
+ String country = locale.Country; if (country == null) country = "";
+ String variant = locale.Variant; if (variant == null) variant = "";
+ javaLocale = new java.util.Locale(language, country, variant);
+ } else {
+ javaLocale = java.util.Locale.getDefault();
+ }
+ }
+ return javaLocale;
+ }
+
+ /**
+ * Provides the supported service names of the implementation,
+ * including also indirect service names.
+ *
+ * @return sequence of service names that are supported.
+ */
+ @Override
+ public final String[] getSupportedServiceNames() {
+ return new String[] {ADDIN_SERVICE, getServiceName()};
+ }
+
+ /**
+ * Tests whether the specified service is supported, i.e. implemented by the implementation.
+ *
+ * @param name name of service to be tested.
+ * @return {@code true} if the service is supported, {@code false} otherwise.
+ */
+ @Override
+ public final boolean supportsService(final String name) {
+ return name.equals(ADDIN_SERVICE) || name.equals(getServiceName());
+ }
+
+ /**
+ * The service name that can be used to create such an object by a factory.
+ * This is defined as a field in the subclass with exactly the following signature:
+ *
+ * {@preformat java
+ * private static final String __serviceName;
+ * }
+ *
+ * @return the service name.
+ */
+ @Override
+ public abstract String getServiceName();
+
+ /**
+ * Provides the implementation name of the service implementation.
+ *
+ * @return unique name of the implementation.
+ */
+ @Override
+ public final String getImplementationName() {
+ return getClass().getName();
+ }
+
+ /**
+ * Returns the programmatic name of the category the function belongs to.
+ * The category name is used to group similar functions together.
+ * The programmatic category name should always be in English, it is never shown to the user.
+ * It is usually one of the names listed in {@code com.sun.star.sheet.XAddIn} interface.
+ *
+ * @param function the exact name of a method within its interface.
+ * @return the category name the specified function belongs to.
+ */
+ @Override
+ public final String getProgrammaticCategoryName(final String function) {
+ final MethodInfo info = methods.get(function);
+ return (info != null) ? info.category : "Add-In";
+ }
+
+ /**
+ * Returns the user-visible name of the category the function belongs to.
+ * This is used when category names are shown to the user.
+ *
+ * @param function the exact name of a method within its interface.
+ * @return the user-visible category name the specified function belongs to.
+ */
+ @Override
+ public final String getDisplayCategoryName(final String function) {
+ return getProgrammaticCategoryName(function);
+ }
+
+ /**
+ * Returns the internal function name for an user-visible name. The user-visible name of a function
+ * is the name shown to the user. It may be translated to the {@linkplain #getLocale() current locale},
+ * so it is never stored in files. It should be a single word and is used when entering or displaying formulas.
+ *
+ * Attention: The method name contains a spelling error.
+ * Due to compatibility reasons the name cannot be changed.
+ *
+ * @param display the user-visible name of a function.
+ * @return the exact name of the method within its interface.
+ */
+ @Override
+ public final String getProgrammaticFuntionName(final String display) {
+ for (final Map.Entry entry : methods.entrySet()) {
+ if (display.equals(entry.getValue().display)) {
+ return entry.getKey();
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Returns the user-visible function name for an internal name.
+ * The user-visible name of a function is the name shown to the user.
+ * It may be translated to the {@linkplain #getLocale() current locale}, so it is never stored in files.
+ * It should be a single word and is used when entering or displaying formulas.
+ *
+ * @param function the exact name of a method within its interface.
+ * @return the user-visible name of the specified function.
+ */
+ @Override
+ public final String getDisplayFunctionName(final String function) {
+ final MethodInfo info = methods.get(function);
+ return (info != null) ? info.display : "";
+ }
+
+ /**
+ * Returns the description of a function.
+ * The description is shown to the user when selecting functions.
+ * It may be translated to the {@linkplain #getLocale() current locale}.
+ *
+ * @param function the exact name of a method within its interface.
+ * @return the description of the specified function.
+ */
+ @Override
+ public final String getFunctionDescription(final String function) {
+ final MethodInfo info = methods.get(function);
+ return (info != null) ? info.description : "";
+ }
+
+ /**
+ * Returns the user-visible name of the specified argument.
+ * The argument name is shown to the user when prompting for arguments.
+ * It should be a single word and may be translated to the {@linkplain #getLocale() current locale}.
+ *
+ * @param function the exact name of a method within its interface.
+ * @param argument the index of the argument (0-based).
+ * @return the user-visible name of the specified argument.
+ */
+ @Override
+ public final String getDisplayArgumentName(final String function, int argument) {
+ final MethodInfo info = methods.get(function);
+ if (info != null) {
+ argument <<= 1;
+ final String[] arguments = info.arguments;
+ if (argument >= 0 && argument < arguments.length) {
+ return arguments[argument];
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Returns the description of the specified argument.
+ * The argument description is shown to the user when prompting for arguments.
+ * It may be translated to the {@linkplain #getLocale() current locale}.
+ *
+ * @param function the exact name of a method within its interface.
+ * @param argument the index of the argument (0-based).
+ * @return the description of the specified argument.
+ */
+ @Override
+ public final String getArgumentDescription(final String function, int argument) {
+ final MethodInfo info = methods.get(function);
+ if (info != null) {
+ argument = (argument << 1) + 1;
+ final String[] arguments = info.arguments;
+ if (argument >= 0 && argument < arguments.length) {
+ return arguments[argument];
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Sets the timezone for time values to be provided to {@link #toDate(XPropertySet, double)}.
+ * If this method is never invoked, then the default timezone is the locale one.
+ *
+ * @param timezone the new timezone.
+ */
+ protected final void setTimeZone(final String timezone) {
+ final TimeZone tz = TimeZone.getTimeZone(timezone);
+ synchronized (this) {
+ if (calendar == null) {
+ calendar = new GregorianCalendar(tz);
+ } else {
+ calendar.setTimeZone(tz);
+ }
+ }
+ }
+
+ /**
+ * Returns the spreadsheet epoch.
+ * The timezone is the one specified during the last invocation of {@link #setTimeZone(String)}.
+ * The epoch is used for date conversions as in {@link #toDate(XPropertySet, double)}.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @return the spreadsheet epoch as a new Java Date object, or {@code null}.
+ */
+ protected final java.util.Date getEpoch(final XPropertySet xOptions) {
+ final Date date;
+ try {
+ date = (Date) AnyConverter.toObject(Date.class, xOptions.getPropertyValue("NullDate"));
+ } catch (Exception e) { // Too many possible exceptions for enumerating all of them.
+ reportException("getEpoch", e, THROW_EXCEPTION);
+ return null;
+ }
+ synchronized (this) {
+ if (calendar == null) {
+ calendar = new GregorianCalendar();
+ }
+ calendar.clear();
+ calendar.set(date.Year, date.Month-1, date.Day);
+ return calendar.getTime();
+ }
+ }
+
+ /**
+ * Converts a date from a spreadsheet value to a Java {@link java.util.Date} object.
+ * The timezone is the one specified during the last invocation of {@link #setTimeZone(String)}.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param time the spreadsheet numerical value for a date, by default in the local timezone.
+ * @return the date as a Java object.
+ */
+ protected final java.util.Date toDate(final XPropertySet xOptions, final double time) {
+ final java.util.Date date = getEpoch(xOptions);
+ if (date != null) {
+ date.setTime(date.getTime() + Math.round(time * DAY_TO_MILLIS));
+ }
+ return date;
+ }
+
+ /**
+ * Converts a date from a Java {@link java.util.Date} object to a spreadsheet value.
+ * The timezone is the one specified during the last invocation of {@link #setTimeZone(String)}.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param time the date as a Java object.
+ * @return the spreadsheet numerical value for a date, by default in the local timezone.
+ */
+ protected final double toDouble(final XPropertySet xOptions, final java.util.Date time) {
+ final java.util.Date epoch = getEpoch(xOptions);
+ if (epoch != null) {
+ return (time.getTime() - epoch.getTime()) / (double) DAY_TO_MILLIS;
+ } else {
+ return Double.NaN;
+ }
+ }
+
+ /**
+ * The string to returns when a formula does not have any value to return.
+ *
+ * @return the string with a message for missing values.
+ * @todo localize.
+ */
+ static String noResultString() {
+ return "(none)";
+ }
+
+ /**
+ * Returns the minimal length of the specified arrays. In the special case where one array
+ * has a length of 1, we assume that this single element will be repeated for all elements
+ * in the other array.
+ */
+ static int getMinimalLength(final Object[] array1, final Object[] array2) {
+ if (array1 == null || array2 == null) {
+ return 0;
+ }
+ if (array1.length == 1) return array2.length;
+ if (array2.length == 1) return array1.length;
+ return Math.min(array1.length, array2.length);
+ }
+
+ /**
+ * Returns the localized message from the specified exception. If no message is available,
+ * returns a default string. This method never return a null value.
+ *
+ * @param exception the exception for which to get the localized message.
+ * @return an error message to report to the user.
+ */
+ protected final String getLocalizedMessage(final Throwable exception) {
+ final String message = Exceptions.getLocalizedMessage(exception, getJavaLocale());
+ if (message != null) {
+ return message;
+ }
+ return Classes.getShortClassName(exception);
+ }
+
+ /**
+ * Returns a table filled with {@link Double#NaN} values.
+ * This method is invoked when an operation failed for a whole table.
+ *
+ * @param rows the number of rows.
+ * @param cols the number of columns.
+ * @return A table of the given size filled with NaN values.
+ */
+ static double[][] getFailure(final int rows, final int cols) {
+ final double[][] dummy = new double[rows][];
+ for (int i=0; iNOTE: OpenOffice expects a field with exactly that name; do not rename!
+ */
+ static final String __serviceName = "org.apache.sis.openoffice.Referencing";
+
+ /**
+ * Constructs a default implementation of {@code XReferencing} interface.
+ */
+ public Referencing() {
+ methods.put("getName", new MethodInfo("Referencing", "CRS.NAME",
+ "Returns a description for an object identified by the given authority code.",
+ new String[] {
+ "xOptions", "Provided by OpenOffice.",
+ "code", "The code allocated by authority."
+ }));
+ methods.put("getDomainOfValidity", new MethodInfo("Referencing", "CRS.VALID.AREA",
+ "Returns the valid area as a geographic bounding box for an identified object.",
+ new String[] {
+ "xOptions", "Provided by OpenOffice.",
+ "code", "The code allocated by authority."
+ }));
+ methods.put("getAxis", new MethodInfo("Referencing", "CRS.AXIS",
+ "Returns the axis name for the specified dimension in an identified object.",
+ new String[] {
+ "xOptions", "Provided by OpenOffice.",
+ "code", "The code allocated by authority.",
+ "dimension", "The dimension (1, 2, ...)."
+ }));
+ methods.put("getAccuracy", new MethodInfo("Referencing", "TRANSFORM.ACCURACY",
+ "Returns the accuracy of a transformation between two coordinate reference systems.",
+ new String[] {
+ "xOptions", "Provided by OpenOffice.",
+ "source CRS", "The source coordinate reference system.",
+ "target CRS", "The target coordinate reference system.",
+ "coordinates", "The coordinate values to transform."
+ }));
+ methods.put("transform", new MethodInfo("Referencing", "TRANSFORM.COORD",
+ "Transform coordinates from the given source CRS to the given target CRS.",
+ new String[] {
+ "xOptions", "Provided by OpenOffice.",
+ "source CRS", "The source coordinate reference system.",
+ "target CRS", "The target coordinate reference system.",
+ "coordinates", "The coordinate values to transform."
+ }));
+ methods.put("parseAngle", new MethodInfo("Text", "VALUE.ANGLE",
+ "Converts text in degrees-minutes-seconds to an angle in decimal degrees.",
+ new String[] {
+ "xOptions", "Provided by OpenOffice.",
+ "text", "The text to be converted to an angle.",
+ "pattern", "The text that describes the format (example: \"D°MM.m'\")."
+ }));
+ methods.put("formatAngle", new MethodInfo("Text", "TEXT.ANGLE",
+ "Converts an angle to text according to a given format.",
+ new String[] {
+ "xOptions", "Provided by OpenOffice.",
+ "value", "The angle value (in decimal degrees) to be converted.",
+ "pattern", "The text that describes the format (example: \"D°MM.m'\")."
+ }));
+ }
+
+ /**
+ * The service name that can be used to create such an object by a factory.
+ */
+ @Override
+ public String getServiceName() {
+ return __serviceName;
+ }
+
+ /**
+ * Gets the CRS or other kind of object from the given code.
+ * If the code is a URN, then it can be any kind of object.
+ * Otherwise a Coordinate Reference System is assumed.
+ * This method caches the result.
+ *
+ * @param codeOrPath the code allocated by an authority, or the path to a file.
+ * @return the identified object for the given code.
+ * @throws FactoryException if an error occurred while creating the object.
+ */
+ private static IdentifiedObject getIdentifiedObject(final String codeOrPath) throws FactoryException {
+ final CacheKey key = new CacheKey<>(IdentifiedObject.class, codeOrPath, null, null);
+ IdentifiedObject object = key.peek();
+ if (object == null) {
+ final Cache.Handler handler = key.lock();
+ try {
+ object = handler.peek();
+ if (object == null) {
+ switch (CodeType.guess(codeOrPath)) {
+ case URN: object = CRS.getAuthorityFactory(null).createObject(codeOrPath); break;
+ default: object = CRS.forCode(codeOrPath); break;
+ }
+ }
+ } finally {
+ handler.putAndUnlock(object);
+ }
+ }
+ return object;
+ }
+
+ /**
+ * Returns the identified object name from an authority code.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param codeOrPath the code allocated by an authority, or the path to a file.
+ * @return the object name.
+ */
+ @Override
+ public String getName(final XPropertySet xOptions, final String codeOrPath) {
+ final InternationalString name;
+ try {
+ final IdentifiedObject object;
+ switch (CodeType.guess(codeOrPath)) {
+ case URN:
+ case CRS: object = new CacheKey<>(IdentifiedObject.class, codeOrPath, null, null).peek(); break;
+ default: object = getIdentifiedObject(codeOrPath); break;
+ }
+ if (object != null) {
+ return object.getName().getCode();
+ }
+ // In Apache SIS implementation, 'getDescriptionText' returns the name.
+ name = CRS.getAuthorityFactory(null).getDescriptionText(codeOrPath);
+ } catch (FactoryException exception) {
+ return getLocalizedMessage(exception);
+ }
+ return (name != null) ? name.toString(getJavaLocale()) : noResultString();
+ }
+
+ /**
+ * Returns the axis name and units for the specified dimension
+ * in a coordinate reference system or coordinate system.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param codeOrPath the code allocated by an authority, or the path to a file.
+ * @param dimension the dimension (1, 2, …).
+ * @return the name of the requested axis.
+ */
+ @Override
+ public String getAxis(final XPropertySet xOptions, final String codeOrPath, final int dimension) {
+ final CacheKey key = new CacheKey<>(String.class, codeOrPath, dimension, null);
+ String name = key.peek();
+ if (name == null) {
+ final Cache.Handler handler = key.lock();
+ try {
+ name = handler.peek();
+ if (name == null) {
+ final IdentifiedObject object;
+ try {
+ object = getIdentifiedObject(codeOrPath);
+ } catch (FactoryException exception) {
+ return getLocalizedMessage(exception);
+ }
+ final CoordinateSystemAxis axis;
+ if (object instanceof CoordinateSystemAxis) {
+ axis = (CoordinateSystemAxis) object;
+ } else {
+ final CoordinateSystem cs;
+ if (object instanceof CoordinateReferenceSystem) {
+ cs = ((CoordinateReferenceSystem) object).getCoordinateSystem();
+ } else if (object instanceof CoordinateSystem) {
+ cs = (CoordinateSystem) object;
+ } else {
+ return Errors.getResources(getJavaLocale()).getString(Errors.Keys.UnexpectedTypeForReference_3,
+ codeOrPath, CoordinateReferenceSystem.class, Classes.getClass(object));
+ }
+ if (dimension >= 1 && dimension <= cs.getDimension()) {
+ axis = cs.getAxis(dimension - 1);
+ } else {
+ return Errors.getResources(getJavaLocale()).getString(Errors.Keys.IndexOutOfBounds_1, dimension);
+ }
+ }
+ final String unit = PatchedUnitFormat.toString(axis.getUnit());
+ name = axis.getName().getCode();
+ if (unit != null && !unit.isEmpty()) {
+ name = name + " (" + unit + ')';
+ }
+ }
+ } finally {
+ handler.putAndUnlock(name);
+ }
+ }
+ return name;
+ }
+
+ /**
+ * Returns the domain of validity as a geographic bounding box for an identified object.
+ * This method returns a 2×2 matrix:
+ * the first row contains the latitude and longitude of upper left corner,
+ * and the second row contains the latitude and longitude of bottom right corner.
+ * Units are degrees.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param codeOrPath the code allocated by an authority, or the path to a file.
+ * @return the object bounding box.
+ */
+ @Override
+ public double[][] getDomainOfValidity(final XPropertySet xOptions, final String codeOrPath) {
+ final CacheKey key = new CacheKey<>(GeographicBoundingBox.class, codeOrPath, null, null);
+ GeographicBoundingBox area = key.peek();
+ if (area == null) {
+ final Cache.Handler handler = key.lock();
+ try {
+ area = handler.peek();
+ if (area == null) try {
+ final IdentifiedObject object = getIdentifiedObject(codeOrPath);
+ final Object domain = IdentifiedObjects.getProperties(object).get(ReferenceSystem.DOMAIN_OF_VALIDITY_KEY);
+ if (domain instanceof Extent) {
+ area = Extents.getGeographicBoundingBox((Extent) domain);
+ }
+ } catch (FactoryException exception) {
+ reportException("getDomainOfValidity", exception, THROW_EXCEPTION);
+ }
+ } finally {
+ handler.putAndUnlock(area);
+ }
+ }
+ if (area == null) {
+ return getFailure(4,4);
+ }
+ return new double[][] {
+ new double[] {area.getNorthBoundLatitude(), area.getWestBoundLongitude()},
+ new double[] {area.getSouthBoundLatitude(), area.getEastBoundLongitude()}};
+ }
+
+ /**
+ * Gets the {@code IdentifiedObject} for the given code as a {@code CoordinateReferenceSystem}.
+ *
+ * @param codeOrPath the code allocated by an authority, or the path to a file.
+ * @return the coordinate reference system for the given code.
+ * @throws FactoryException if an error occurred while creating the object.
+ */
+ final CoordinateReferenceSystem getCRS(final String codeOrPath) throws FactoryException {
+ final IdentifiedObject object = getIdentifiedObject(codeOrPath);
+ if (object == null || object instanceof CoordinateReferenceSystem) {
+ return (CoordinateReferenceSystem) object;
+ }
+ throw new FactoryException(Errors.getResources(getJavaLocale()).getString(
+ Errors.Keys.UnexpectedTypeForReference_3, codeOrPath,
+ CoordinateReferenceSystem.class, Classes.getClass(object)));
+ }
+
+ /**
+ * Returns the accuracy of a transformation between two coordinate reference systems.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param sourceCRS the authority code for the source coordinate reference system.
+ * @param targetCRS the authority code for the target coordinate reference system.
+ * @param points the coordinates to transform (for computing area of interest).
+ * @return the operation accuracy.
+ */
+ @Override
+ public double getAccuracy(final XPropertySet xOptions,
+ final String sourceCRS, final String targetCRS, final double[][] points)
+ {
+ try {
+ return new Transformer(this, getCRS(sourceCRS), targetCRS, points).getAccuracy();
+ } catch (FactoryException exception) {
+ reportException("getAccuracy", exception, THROW_EXCEPTION);
+ return Double.NaN;
+ }
+ }
+
+ /**
+ * Transforms coordinates from the specified source CRS to the specified target CRS.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param sourceCRS the authority code for the source coordinate reference system.
+ * @param targetCRS the authority code for the target coordinate reference system.
+ * @param points the coordinates to transform.
+ * @return The transformed coordinates.
+ */
+ @Override
+ public double[][] transformCoordinates(final XPropertySet xOptions,
+ final String sourceCRS, final String targetCRS, final double[][] points)
+ {
+ try {
+ return new Transformer(this, getCRS(sourceCRS), targetCRS, points).transform(points);
+ } catch (FactoryException exception) {
+ reportException("transformCoordinates", exception, THROW_EXCEPTION);
+ return getFailure(points.length, 2);
+ }
+ }
+
+ /**
+ * Converts text in degrees-minutes-seconds to an angle in decimal degrees.
+ * See {@link org.apache.sis.measure.AngleFormat} for pattern description.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param text the text to be converted to an angle.
+ * @param pattern an optional text that describes the format (example: "D°MM.m'").
+ * @return the angle parsed as a number.
+ * @throws IllegalArgumentException if {@code pattern} is illegal.
+ */
+ @Override
+ public double parseAngle(final XPropertySet xOptions,
+ final String text,
+ final Object pattern)
+ throws IllegalArgumentException
+ {
+ try {
+ return new AnglePattern(pattern).parse(text, getJavaLocale());
+ } catch (ParseException exception) {
+ reportException("parseAngle", exception, THROW_EXCEPTION);
+ return Double.NaN;
+ }
+ }
+
+ /**
+ * Converts an angle to text according to a given format. This method uses the pattern
+ * described by {@link org.apache.sis.measure.AngleFormat} with the following extension:
+ *
+ *
+ * - If the pattern ends with E or W, then the angle is formatted as a longitude.
+ * - If the pattern ends with N or S, then the angle is formatted as a latitude.
+ *
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param value the angle value (in decimal degrees) to be converted.
+ * @param pattern an optional text that describes the format (example: "D°MM.m'").
+ * @return the angle formatted as a string.
+ * @throws IllegalArgumentException if {@code pattern} is illegal.
+ */
+ @Override
+ public String formatAngle(final XPropertySet xOptions,
+ final double value,
+ final Object pattern)
+ throws IllegalArgumentException
+ {
+ return new AnglePattern(pattern).format(value, getJavaLocale());
+ }
+}
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Referencing.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Referencing.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java?rev=1747091&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java (added)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java [UTF-8] Mon Jun 6 23:33:04 2016
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.openoffice;
+
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.geometry.GeneralDirectPosition;
+import org.apache.sis.referencing.CRS;
+import org.apache.sis.util.collection.Cache;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
+import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
+
+
+/**
+ * Applies a coordinate transformation between two CRS.
+ *
+ * @author Martin Desruisseaux (IRD, Geomatys)
+ * @since 0.8
+ * @version 0.8
+ * @module
+ */
+final class Transformer {
+ /**
+ * The geographic area of interest. All values are in degrees. Prime meridian is Greenwich.
+ * Datum does not need to be specified since area of interest is an approximative information.
+ *
+ * @see #hasAreaOfInterest()
+ */
+ private double westBoundLongitude, eastBoundLongitude,
+ southBoundLatitude, northBoundLatitude;
+
+ /**
+ * The coordinate operation.
+ */
+ private CoordinateOperation operation;
+
+ /**
+ * The first error that occurred while transforming points, or {@code null} if none.
+ */
+ TransformException warning;
+
+ /**
+ * Creates a new transformer.
+ */
+ Transformer(final Referencing caller, final CoordinateReferenceSystem sourceCRS,
+ final String targetCRS, final double[][] points) throws FactoryException
+ {
+ /*
+ * Computes the area of interest.
+ */
+ final GeographicCRS domainCRS = ReferencingUtilities.toNormalizedGeographicCRS(sourceCRS);
+ if (domainCRS != null) {
+ final MathTransform toDomainOfValidity = CRS.findOperation(sourceCRS, domainCRS, null).getMathTransform();
+ final int dimension = toDomainOfValidity.getSourceDimensions();
+ final double[] domainCoord = new double[toDomainOfValidity.getTargetDimensions()];
+ if (domainCoord.length >= 2) {
+ westBoundLongitude = Double.POSITIVE_INFINITY;
+ southBoundLatitude = Double.POSITIVE_INFINITY;
+ eastBoundLongitude = Double.NEGATIVE_INFINITY;
+ northBoundLatitude = Double.NEGATIVE_INFINITY;
+ for (final double[] coord : points) {
+ if (coord.length == dimension) {
+ try {
+ toDomainOfValidity.transform(coord, 0, domainCoord, 0, 1);
+ } catch (TransformException e) {
+ if (warning == null) {
+ warning = e;
+ }
+ continue;
+ }
+ final double x = domainCoord[0];
+ final double y = domainCoord[1];
+ if (x < westBoundLongitude) westBoundLongitude = x;
+ if (x > eastBoundLongitude) eastBoundLongitude = x;
+ if (y < southBoundLatitude) southBoundLatitude = y;
+ if (y > northBoundLatitude) northBoundLatitude = y;
+ }
+ }
+ }
+ }
+ /*
+ * Get the coordinate operation from the cache if possible, or compute it otherwise.
+ */
+ final boolean hasAreaOfInterest = hasAreaOfInterest();
+ final CacheKey key = new CacheKey<>(CoordinateOperation.class, targetCRS, sourceCRS,
+ hasAreaOfInterest ? new double[] {westBoundLongitude, eastBoundLongitude,
+ southBoundLatitude, northBoundLatitude} : null);
+ operation = key.peek();
+ if (operation == null) {
+ final Cache.Handler handler = key.lock();
+ try {
+ operation = handler.peek();
+ if (operation == null) {
+ operation = CRS.findOperation(sourceCRS, caller.getCRS(targetCRS),
+ hasAreaOfInterest ? new DefaultGeographicBoundingBox(
+ westBoundLongitude, eastBoundLongitude,
+ southBoundLatitude, northBoundLatitude) : null);
+ }
+ } finally {
+ handler.putAndUnlock(operation);
+ }
+ }
+ }
+
+ /**
+ * Returns {@code true} if the area of interest is non-empty.
+ */
+ private boolean hasAreaOfInterest() {
+ return (westBoundLongitude < eastBoundLongitude) && (southBoundLatitude < northBoundLatitude);
+ }
+
+ /**
+ * Returns the accuracy in metres.
+ */
+ final double getAccuracy() {
+ return AbstractCoordinateOperation.castOrCopy(operation).getLinearAccuracy();
+ }
+
+ /**
+ * Transforms the given points.
+ */
+ final double[][] transform(final double[][] points) {
+ final MathTransform mt = operation.getMathTransform();
+ final GeneralDirectPosition sourcePt = new GeneralDirectPosition(mt.getSourceDimensions());
+ final GeneralDirectPosition targetPt = new GeneralDirectPosition(mt.getTargetDimensions());
+ final double[][] result = new double[points.length][];
+ for (int j=0; j=0;) {
+ sourcePt.ordinates[i] = (i < coords.length) ? coords[i] : 0;
+ }
+ try {
+ result[j] = mt.transform(sourcePt, targetPt).getCoordinate();
+ } catch (TransformException exception) {
+ /*
+ * The coordinate operation failed for this particular point. But maybe it will
+ * succeed for an other point. Set the values to NaN and continue the loop. Note:
+ * we will report the failure for logging purpose, but only the first one since
+ * all subsequent failures are likely to be the same one.
+ */
+ if (warning == null) {
+ warning = exception;
+ }
+ }
+ }
+ }
+ return result;
+ }
+}
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.idl
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.idl?rev=1747091&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.idl (added)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.idl [UTF-8] Mon Jun 6 23:33:04 2016
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _org_apache_sis_openoffice_XReferencing_
+#define _org_apache_sis_openoffice_XReferencing_
+
+#include
+#include
+#include
+
+
+module org {
+ module apache {
+ module sis {
+ module openoffice {
+ /// Methods from the org.apache.sis.referencing package to make available to OpenOffice.
+ interface XReferencing : com::sun::star::uno::XInterface {
+ /// Returns an identified object name from an authority code.
+ string getName(
+ [in] com::sun::star::beans::XPropertySet xOptions,
+ /// The authority code (e.g. "EPSG:4326").
+ [in] string authorityCode
+ );
+
+ /// Returns the axis name for the specified dimension in an identified object.
+ string getAxis(
+ [in] com::sun::star::beans::XPropertySet xOptions,
+ /// The authority code (e.g. "EPSG:4326").
+ [in] string authorityCode,
+ /// The dimension (1, 2, ...).
+ [in] long dimension
+ );
+
+ /// Returns the domain of validity as a geographic bounding box for an identified object.
+ sequence< sequence< double > > getDomainOfValidity(
+ [in] com::sun::star::beans::XPropertySet xOptions,
+ /// The authority code (e.g. "EPSG:4326").
+ [in] string authorityCode
+ );
+
+ /// Returns the accuracy of a transformation between two coordinate reference systems.
+ double getAccuracy(
+ [in] com::sun::star::beans::XPropertySet xOptions,
+ /// The source coordinates to transform.
+ [in] string sourceCRS,
+ /// Authority code of the target coordinate reference system.
+ [in] string targetCRS,
+ /// The source coordinates to transform.
+ [in] sequence< sequence< double > > coordinates
+ );
+
+ /// Transforms a list of coordinates from source CRS to target CRS.
+ sequence< sequence< double > > transformCoordinates(
+ [in] com::sun::star::beans::XPropertySet xOptions,
+ /// Authority code of the source coordinate reference system.
+ [in] string sourceCRS,
+ /// Authority code of the target coordinate reference system.
+ [in] string targetCRS,
+ /// The source coordinates to transform.
+ [in] sequence< sequence< double > > coordinates
+ );
+
+ /// Converts text in degrees-minutes-seconds to an angle in decimal degrees.
+ double parseAngle(
+ [in] com::sun::star::beans::XPropertySet xOptions,
+ /// The text to be converted to an angle.
+ [in] string text,
+ /// The text that describes the format (example: "D MM.m'").
+ [in] any pattern
+ ) raises (com::sun::star::lang::IllegalArgumentException);
+
+ /// Converts an angle to text according to a given format.
+ string formatAngle(
+ [in] com::sun::star::beans::XPropertySet xOptions,
+ /// The angle value (in decimal degrees) to be converted.
+ [in] double value,
+ /// The text that describes the format (example: "D MM.m'").
+ [in] any pattern
+ ) raises (com::sun::star::lang::IllegalArgumentException);
+ };
+
+ /*
+ * Exported interfaces:
+ * This is where we put all interfaces that this service exports.
+ */
+ service Referencing {
+ interface XReferencing;
+
+ /*
+ * Necessary base service.
+ * All add-ins must implement this service.
+ */
+ service com::sun::star::sheet::AddIn;
+ };
+ };
+ };
+ };
+};
+
+#endif
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.idl
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.idl
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.java?rev=1747091&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.java (added)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.java [UTF-8] Mon Jun 6 23:33:04 2016
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.openoffice;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.IllegalArgumentException;
+
+
+/**
+ * Services from the {@link org.apache.sis.referencing} package to be exported to Apache
+ * OpenOffice or LibreOffice.
+ *
+ * This interface is derived from the {@code XReferencing.idl} file by first compiling with the {@code javamaker}
+ * tool provided in OpenOffice SDK, then disassembling the output using the {@code javap} tool provided in Java SDK.
+ * This source file exists only for convenience: for avoiding that IDEs report errors, and opportunistically for
+ * Javadoc purpose. But the {@code XReferencing.class} file compiled from this source file must
+ * be overwritten by the {@code XReferencing.class} file generated by {@code javamaker}.
+ * See {@code application/sis-openoffice/src/main/unopkg/build-instruction.html} for more information.
+ *
+ * @author Martin Desruisseaux (IRD, Geomatys)
+ * @since 0.8
+ * @version 0.8
+ * @module
+ */
+public interface XReferencing extends XInterface {
+ /**
+ * Returns the identified object name from an authority code.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param codeOrPath the code allocated by an authority, or the path to a file.
+ * @return the object name.
+ */
+ String getName(XPropertySet xOptions, String codeOrPath);
+
+ /**
+ * Returns the axis name and units for the specified dimension
+ * in a coordinate reference system or coordinate system.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param codeOrPath the code allocated by an authority, or the path to a file.
+ * @param dimension the dimension (1, 2, …).
+ * @return the name of the requested axis.
+ */
+ String getAxis(XPropertySet xOptions, String codeOrPath, int dimension);
+
+ /**
+ * Returns the domain of validity as a geographic bounding box for an identified object.
+ * This method returns a 2×2 matrix:
+ * the first row contains the latitude and longitude of upper left corner,
+ * and the second row contains the latitude and longitude of bottom right corner.
+ * Units are degrees.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param codeOrPath the code allocated by an authority, or the path to a file.
+ * @return the object bounding box.
+ */
+ double[][] getDomainOfValidity(XPropertySet xOptions, String codeOrPath);
+
+ /**
+ * Returns the accuracy of a transformation between two coordinate reference systems.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param sourceCRS the authority code for the source coordinate reference system.
+ * @param targetCRS the authority code for the target coordinate reference system.
+ * @param points the coordinates to transform (for computing area of interest).
+ * @return the operation accuracy.
+ */
+ double getAccuracy(XPropertySet xOptions, String sourceCRS, String targetCRS, double[][] points);
+
+ /**
+ * Transforms coordinates from the specified source CRS to the specified target CRS.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param sourceCRS the authority code for the source coordinate reference system.
+ * @param targetCRS the authority code for the target coordinate reference system.
+ * @param points the coordinates to transform.
+ * @return The transformed coordinates.
+ */
+ double[][] transformCoordinates(XPropertySet xOptions, String sourceCRS, String targetCRS, double[][] points);
+
+ /**
+ * Converts text in degrees-minutes-seconds to an angle in decimal degrees.
+ * See {@link org.apache.sis.measure.AngleFormat} for pattern description.
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param text the text to be converted to an angle.
+ * @param pattern an optional text that describes the format (example: "D°MM.m'").
+ * @return the angle parsed as a number.
+ * @throws IllegalArgumentException if {@code pattern} is illegal.
+ */
+ double parseAngle(XPropertySet xOptions, String text, Object pattern)
+ throws IllegalArgumentException;
+
+ /**
+ * Converts an angle to text according to a given format. This method uses the pattern
+ * described by {@link org.apache.sis.measure.AngleFormat} with the following extension:
+ *
+ *
+ * - If the pattern ends with E or W, then the angle is formatted as a longitude.
+ * - If the pattern ends with N or S, then the angle is formatted as a latitude.
+ *
+ *
+ * @param xOptions provided by OpenOffice.
+ * @param value the angle value (in decimal degrees) to be converted.
+ * @param pattern an optional text that describes the format (example: "D°MM.m'").
+ * @return the angle formatted as a string.
+ * @throws IllegalArgumentException if {@code pattern} is illegal.
+ */
+ String formatAngle(XPropertySet xOptions, double value, Object pattern)
+ throws IllegalArgumentException;
+}
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/XReferencing.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/package-info.java?rev=1747091&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/package-info.java (added)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/package-info.java [UTF-8] Mon Jun 6 23:33:04 2016
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Apache SIS services made available to Apache OpenOffice or LibreOffice.
+ * Functions to make available in OpenOffice are defined in {@code X*.idl} files,
+ * which are converted to {@code X*.java} files for convenience.
+ *
+ * Note that the {@code X*.class} files to be included in the final JAR file
+ * shall be compiled from the {@code X*.idl} files, not from the {@code X*.java} files.
+ * See {@code application/sis-openoffice/src/main/unopkg/build-instruction.html} for more information.
+ *
+ * @author Martin Desruisseaux (IRD, Geomatys)
+ * @since 0.8
+ * @version 0.8
+ * @module
+ */
+package org.apache.sis.openoffice;
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/package-info.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8