Package org.geotools.data.efeature

Source Code of org.geotools.data.efeature.EFeatureContextFactory

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2002-2011, Open Source Geospatial Foundation (OSGeo)
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation;
*    version 2.1 of the License.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*/
package org.geotools.data.efeature;

import java.awt.RenderingHints.Key;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.imageio.spi.ServiceRegistry;

import org.geotools.data.efeature.impl.EFeatureContextImpl;
import org.geotools.data.efeature.impl.EFeatureIDFactoryImpl;
import org.geotools.factory.BufferedFactory;
import org.geotools.util.logging.Logging;

/**
* This class implements a cache of {@link EFeatureContext} instances.
* <p>
* Each {@link EFeatureContext instance} is associated with a factory ID. The
* reference to each cached {@link EFeatureContext is} is strong (ordinary Java
* object reference), ensuring that instances can not be garbage collected, even
* if more memory is needed.  
* </p>
*
* @author kengu
*
*
* @source $URL$
*/
public class EFeatureContextFactory implements BufferedFactory {

    /**
     * Cached {@link Logger} instance for this class
     */
    private static final Logger LOGGER = Logging.getLogger(EFeatureContextFactory.class);
   
    /**
     * Weak reference to instance cached by the
     * {@link ServiceRegistry service registry}.
     */
    private static WeakReference<EFeatureContextFactory> eInstance;
   
    /**
     * {@link Map} containing {@link EFeatureContext} instances.
     */
    private final Map<String, EFeatureContext>
        eContextMap = new HashMap<String, EFeatureContext>();
   
    /**
     * {@link Map} containing {@link EFeatureContextInfo} instances.
     */
    private final Map<String, EFeatureContextInfo>
        eContextInfoMap = new HashMap<String, EFeatureContextInfo>();

    // -----------------------------------------------------
    //  Constructors
    // -----------------------------------------------------
   
    /**
     * Default construction (required by SPI)
     */
    public EFeatureContextFactory() { /*NOP*/ }
   
   
    // -----------------------------------------------------
    //  Static helper methods
    // -----------------------------------------------------

    /**
     * Get instance cached by {@link EFeatureFactoryFinder}
     */
    public static EFeatureContextFactory eDefault(){
        if(eInstance==null || eInstance.get()==null)
        {
            eInstance = new WeakReference<EFeatureContextFactory>(
                    EFeatureFactoryFinder.getContextFactory());
        }
        return eInstance.get();
    }
   
    /**
     * Check to see if {@link EFeatureDataStore}s can be created.
     * <p>
     * This factory is only available if at least one
     * {@link EFeatureContext} instance is registered.
     * <p>
     *
     * @return <code>true</code> if and only if this factory is available to create
     *         {@link EFeatureDataStore}s.
     *
     */
    public boolean isAvailable() {
        return EFeatureUtils.isAvailable(eContextInfoMap);
    }
   
    /**
     * Check if given {@link EFeatureContext} instance is created by this factory.
     * <p>
     * This method checks for {@link Map#containsValue(Object) value equality}
     * between given instance and cached instances.
     * </p>
     * @param eContext - a {@link EFeatureContext} instance
     * @return <code>true</code> if found.
     * @see {@link #contains(String)}
     */
    public boolean contains(EFeatureContext eContext)
    {
        return eContextMap.containsValue(eContext);
    }
   
    /**
     * Check if a {@link EFeatureContext} instance with given ID is created by this factory.
     * <p>
     * This method checks for {@link Map#containsKey(Object) key equality}
     * between given ID and cached IDs.
     * </p>
     * @param eContextID - {@link EFeature} context {@link EFeatureContext#get id}
     * @return <code>true</code> if found.
     */
    public boolean contains(String eContextID)
    {
        return eContextMap.containsKey(eContextID);
    }
   
    /**
     * Create a {@link EFeatureContext} instance with given ID.
     * </p>
     * @return a {@link EFeatureContext} instance.
     * @throws IllegalArgumentException If an another instance with
     * same eContextID already exist.
     * {@link EFeatureContext instance}.
     */
    public EFeatureContext create(String eContextID) throws IllegalArgumentException
    {
        return create(eContextID,new EFeatureIDFactoryImpl(), new EFeatureHints());
    }
   
    /**
     * Create a {@link EFeatureContextInfo} instance from given
     * {@link EFeatureContext} instance and cache both instances.
     * <p>
     * If instance has already joined this factory, this method returns the cached
     * {@link EFeatureContextInfo} instance.
     * </p>
     * @param eContextID
     * @param eHints - {@link EFeatureHints} instance
     * @return a {@link EFeatureContextInfo} instance.
     * @throws IllegalArgumentException If an another instance with
     * same eContextID already exist.
     * {@link EFeatureContext instance}.
     */
    public EFeatureContext create(String eContextID, EFeatureHints eHints) throws IllegalArgumentException
    {
        return create(eContextID,new EFeatureIDFactoryImpl(),eHints);
    }
   
    /**
     * Create a {@link EFeatureContextInfo} instance from given
     * {@link EFeatureContext} instance and cache both instances.
     * <p>
     * If instance has already joined this factory, this method returns the cached
     * {@link EFeatureContextInfo} instance.
     * </p>
     * @param eContextID
     * @param eIDFactory
     * @param eHints - {@link EFeatureHints} instance
     * @return a {@link EFeatureContextInfo} instance.
     * @throws IllegalArgumentException If an another instance with
     * same eContextID already exist.
     * {@link EFeatureContext instance}.
     */
    public EFeatureContext create(String eContextID, EFeatureIDFactory eIDFactory, EFeatureHints eHints) throws IllegalArgumentException
    {
        try {
            //
            // Use default factory?
            //
            if(eIDFactory==null) eIDFactory = new EFeatureIDFactoryImpl();
            //
            // Use default hints?
            //
            if(eHints==null) eHints = new EFeatureHints();
            //
            // Another instance already registered with given ID?
            //
            EFeatureContextInfo eContextInfo = eContextInfoMap.get(eContextID);
            if(eContextInfo != null)
            {
                throw new IllegalArgumentException(
                        "EFeatureContext " + eContextID + "' already exists");
            }
            //
            // All OK, go ahead and create context and structure.
            //
            EFeatureContext eContext = new EFeatureContextImpl(this, eContextID, eIDFactory);
            //
            // Map context to id (required by subsequent create methods)
            //
            eContextMap.put(eContextID, eContext);
            //
            // Create structure info object
            //
            eContextInfo = EFeatureContextInfo.create(this,eContextID, eHints);
            //
            // Map structure to id
            //
            eContextInfoMap.put(eContextID, eContextInfo);
            //
            // -----------------------------------------------------
            //  Add EFeature as prototype.
            // -----------------------------------------------------
            //  This is an important step. It allows the context to
            //  filter on any EFeature implementation, and enables
            //  _ANY_ EFeature implementation to be adapted into
            //  this context.
            // -----------------------------------------------------
            //
            EFeaturePackage ePackage = EFeaturePackage.eINSTANCE;
            eContext.eAdd(ePackage);
            EFeatureInfo eFeatureInfo = EFeatureInfo.create(eContext, ePackage.getEFeature(), eHints);
            //
            // -----------------------------------------------------
            //  Validate structure (required)
            // -----------------------------------------------------
            //  This is an important step. If not done,
            //  access to methods like getFeatureType() and
            //  getSRID() will return null or throw exceptions.
            // -----------------------------------------------------
            //
            eFeatureInfo.validate(ePackage, null);
            //
            // Success!
            //
            return eContext;
        }
        catch (IllegalArgumentException e) {
            //
            // Remove context and structure from cache
            //
            eContextMap.remove(eContextID);
            eContextInfoMap.remove(eContextID);
            //
            // Log the error
            //
            LOGGER.throwing(getClass().getName(), "create(EFeatureContext)", e);
            //
            // Notify again
            //
            throw e;
        }
    }
   
    /**
     * Dispose given {@link EFeatureContext context}.
     * </p>
     * @param eContext - the {@link EFeatureContext} instance.
     * @throws IllegalArgumentException If given context is not
     * created by this factory.
     */
    public void dispose(EFeatureContext eContext) {
        if(!contains(eContext)) {
            throw new IllegalArgumentException("Context "
                    + (eContext !=null ? eContext.eContextID() : "null")
                    + " is not created by this factory");
        }
        //
        // Get ID
        //
        String eContextID = eContext.eContextID();
        //
        // Dispose structure
        //
        eStructure(eContextID).dispose();
        //
        // Remove context from cache, allowing garbage collections
        //
        eContextMap.remove(eContextID);
        //
        // Tell garbage collector that memory can possible be reclaimed
        //
        Runtime.getRuntime().gc();
    }
   
    /**
     * Dispose {@link EFeatureContext context} with given id.
     * </p>
     * @param eContextID - the {@link EFeatureContext} id.
     * @throws IllegalArgumentException If given context is not
     * created by this factory.
     */
    public void dispose(String eContextID) {
        if(!contains(eContextID)) {
            throw new IllegalArgumentException("Context "
                    + eContextID + " is not created by this factory");
        }
        dispose(eContextMap.get(eContextID));       
    }

    /**
     * Get a EFeature {@link EFeatureContextInfo registry info} instance.
     * <p>
     * <strong>NOTE</strong>: If no instance was found, a
     * {@link IllegalArgumentException} it thrown.   
     * </p>
     * @param eContextID - id of requested {@link EFeatureContextInfo} instance 
     * @return a {@link EFeatureContextInfo} instance.
     * @throws IllegalArgumentException If no {@link EFeatureContext} instance with
     * given ID was found.
     */
    public EFeatureContextInfo eStructure(String eContextID) throws IllegalArgumentException
    {
        EFeatureContextInfo eContextInfo =  eContextInfoMap.get(eContextID);
        if(eContextInfo == null)
        {
            throw new IllegalArgumentException("EFeatureContext instance with ID "
                    + eContextID + " was not found");
        }
        return eContextInfo;
       
    }
   
    /**
     * Get a EFeature {@link EFeatureContext context} instance.
     * </p>
     * @param eContextID - id of requested {@link EFeatureContext} instance
     * @return a {@link EFeatureContextInfo} instance.
     * @throws IllegalArgumentException If no {@link EFeatureContext}
     * instance was found.
     */
    public EFeatureContext eContext(String eContextID)
    {
        EFeatureContext eContext = eContextMap.get(eContextID);
        if(eContext == null)
        {
            throw new IllegalArgumentException(
                    "EFeatureContext '" + eContextID + "' does not exist");
        }
        return eContext;
    }

    @Override
    public Map<Key, ?> getImplementationHints() {
        //
        // TODO: Add hints for controlling cache size etc.
        //
        return Collections.emptyMap();
    }
   

}
TOP

Related Classes of org.geotools.data.efeature.EFeatureContextFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.