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: + * + * + * + * @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