Search in sources :

Example 1 with Cache

use of org.apache.sis.util.collection.Cache in project sis by apache.

the class ConcurrentAuthorityFactory method createFromCoordinateReferenceSystemCodes.

/**
 * Returns operations from source and target coordinate reference system codes.
 * The default implementation performs the following steps:
 * <ul>
 *   <li>Returns the cached collection for the given pair of codes if such collection already exists.</li>
 *   <li>Otherwise:
 *     <ol>
 *       <li>get an instance of the Data Access Object,</li>
 *       <li>delegate to its {@link GeodeticAuthorityFactory#createFromCoordinateReferenceSystemCodes(String, String)} method,</li>
 *       <li>release the Data Access Object — <em>this step assumes that the collection obtained at step 2
 *           is still valid after the Data Access Object has been released</em>,</li>
 *       <li>cache the result — <em>this step assumes that the collection obtained at step 2 is immutable</em>.</li>
 *     </ol>
 *   </li>
 * </ul>
 *
 * @return the operations from {@code sourceCRS} to {@code targetCRS}.
 * @throws FactoryException if the object creation failed.
 */
@Override
@SuppressWarnings("unchecked")
public Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(final String sourceCRS, final String targetCRS) throws FactoryException {
    ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
    ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
    final Key key = new Key(normalizeCode(sourceCRS), normalizeCode(targetCRS));
    Object value = cache.peek(key);
    if (!(value instanceof Set<?>)) {
        final Cache.Handler<Object> handler = cache.lock(key);
        try {
            value = handler.peek();
            if (!(value instanceof Set<?>)) {
                final DAO factory = getDataAccess();
                try {
                    value = factory.createFromCoordinateReferenceSystemCodes(sourceCRS, targetCRS);
                } finally {
                    release("createFromCoordinateReferenceSystemCodes", CoordinateOperation.class, null);
                }
            }
        } finally {
            handler.putAndUnlock(value);
        }
    }
    return (Set<CoordinateOperation>) value;
}
Also used : Set(java.util.Set) IdentifiedObject(org.opengis.referencing.IdentifiedObject) Cache(org.apache.sis.util.collection.Cache)

Example 2 with Cache

use of org.apache.sis.util.collection.Cache in project sis by apache.

the class ConcurrentAuthorityFactory method create.

/**
 * Returns an object from a code using the given proxy. This method first checks in the cache.
 * If no object exists in the cache for the given code, then a lock is created and the object
 * creation is delegated to the {@linkplain #getDataAccess() Data Access Object}.
 * The result is then stored in the cache and returned.
 *
 * @param  <T>    the type of the object to be returned.
 * @param  proxy  the proxy to use for creating the object.
 * @param  code   the code of the object to create.
 * @return the object extracted from the cache or created.
 * @throws FactoryException if an error occurred while creating the object.
 */
private <T> T create(final AuthorityFactoryProxy<T> proxy, final String code) throws FactoryException {
    ArgumentChecks.ensureNonNull("code", code);
    final Class<T> type = proxy.type;
    final Key key = new Key(type, normalizeCode(code));
    Object value = cache.peek(key);
    if (!type.isInstance(value)) {
        final Cache.Handler<Object> handler = cache.lock(key);
        try {
            value = handler.peek();
            if (!type.isInstance(value)) {
                final T result;
                final DAO factory = getDataAccess();
                try {
                    result = proxy.create(factory, key.code);
                } finally {
                    release(null, type, code);
                }
                if (isCacheable(code, result)) {
                    // For the finally block below.
                    value = result;
                }
                return result;
            }
        } finally {
            handler.putAndUnlock(value);
        }
    }
    return type.cast(value);
}
Also used : IdentifiedObject(org.opengis.referencing.IdentifiedObject) Cache(org.apache.sis.util.collection.Cache)

Example 3 with Cache

use of org.apache.sis.util.collection.Cache in project sis by apache.

the class DefaultCoordinateOperationFactory method createOperation.

/**
 * Finds or creates an operation for conversion or transformation between two coordinate reference systems.
 * If an operation exists, it is returned. If more than one operation exists, then the operation having the
 * widest intersection between its {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of
 * validity} and the {@linkplain CoordinateOperationContext#getAreaOfInterest() area of interest} is returned.
 *
 * <p>The default implementation performs the following steps:</p>
 * <ul>
 *   <li>If a coordinate operation has been previously cached for the given CRS and context, return it.</li>
 *   <li>Otherwise:
 *     <ol>
 *       <li>Invoke {@link #createOperationFinder(CoordinateOperationAuthorityFactory, CoordinateOperationContext)}.</li>
 *       <li>Invoke {@link CoordinateOperationFinder#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)}
 *           on the object returned by the previous step.</li>
 *       <li>Cache the result, then return it.</li>
 *     </ol>
 *   </li>
 * </ul>
 *
 * Subclasses can override {@link #createOperationFinder createOperationFinder(…)} if they need more control on
 * the way coordinate operations are inferred.
 *
 * @param  sourceCRS  input coordinate reference system.
 * @param  targetCRS  output coordinate reference system.
 * @param  context    area of interest and desired accuracy, or {@code null}.
 * @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}.
 * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} to {@code targetCRS}.
 * @throws FactoryException if the operation creation failed for some other reason.
 *
 * @see CoordinateOperationFinder
 *
 * @since 0.7
 */
public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS, final CoordinateOperationContext context) throws OperationNotFoundException, FactoryException {
    final Cache.Handler<CoordinateOperation> handler;
    CoordinateOperation op;
    if (context == null) {
        final CRSPair key = new CRSPair(sourceCRS, targetCRS);
        op = cache.peek(key);
        if (op != null) {
            return op;
        }
        handler = cache.lock(key);
    } else {
        // We currently do not cache the operation when the result may depend on the context (see 'this.cache' javadoc).
        handler = null;
        op = null;
    }
    try {
        if (handler == null || (op = handler.peek()) == null) {
            final AuthorityFactory registry = USE_EPSG_FACTORY ? CRS.getAuthorityFactory(Constants.EPSG) : null;
            op = createOperationFinder((registry instanceof CoordinateOperationAuthorityFactory) ? (CoordinateOperationAuthorityFactory) registry : null, context).createOperation(sourceCRS, targetCRS);
        }
    } finally {
        if (handler != null) {
            handler.putAndUnlock(op);
        }
    }
    return op;
}
Also used : AuthorityFactory(org.opengis.referencing.AuthorityFactory) Cache(org.apache.sis.util.collection.Cache)

Aggregations

Cache (org.apache.sis.util.collection.Cache)3 IdentifiedObject (org.opengis.referencing.IdentifiedObject)2 Set (java.util.Set)1 AuthorityFactory (org.opengis.referencing.AuthorityFactory)1