Package org.geotools.xacml.geoxacml.cond

Source Code of org.geotools.xacml.geoxacml.cond.GeoXACMLFunctionBase

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2008, 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.xacml.geoxacml.cond;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.xacml.geoxacml.attr.GeometryAttribute;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;

import com.sun.xacml.cond.EvaluationResult;
import com.sun.xacml.cond.FunctionBase;
import com.sun.xacml.ctx.Status;
import com.vividsolutions.jts.geom.Geometry;

/**
* @author Christian Mueller
*
*         Abstract base class for GeoXACML functions.
*
*         Also responsible for coordinate transformations. WGS84 is the common CRS, if
*         transformation has to be done, the target CRS is always WGS84
*
*/
public abstract class GeoXACMLFunctionBase extends FunctionBase {

    protected static final String NAME_PREFIX = "urn:ogc:def:function:geoxacml:1.0:";

    protected static final String COMMON_CRS_NAME = "EPSG:4326";

    protected static CoordinateReferenceSystem COMMON_CRS = null;

    public GeoXACMLFunctionBase(String functionName, int functionId, String paramType,
            boolean paramIsBag, int numParams, int minParams, String returnType, boolean returnsBag) {
        super(functionName, functionId, paramType, paramIsBag, numParams, minParams, returnType,
                returnsBag);
    }

    public GeoXACMLFunctionBase(String functionName, int functionId, String paramType,
            boolean paramIsBag, int numParams, String returnType, boolean returnsBag) {
        super(functionName, functionId, paramType, paramIsBag, numParams, returnType, returnsBag);
    }

    public GeoXACMLFunctionBase(String functionName, int functionId, String returnType,
            boolean returnsBag) {
        super(functionName, functionId, returnType, returnsBag);
    }

    public GeoXACMLFunctionBase(String functionName, int functionId, String[] paramTypes,
            boolean[] paramIsBag, String returnType, boolean returnsBag) {
        super(functionName, functionId, paramTypes, paramIsBag, returnType, returnsBag);
    }

    /**
     * @param array
     *            array of GeometryAttributes, length == 2
     * @return array with possible replaced GeometryAttributes (transformed to WGS84)
     * @throws GeoXACMLException
     *
     *             This method tries to avoid transformations.
     *
     *             No transformation in the following situations:
     *
     *             1) Both have no srsName (null) 2) Both have srsNames and equalsIgnoreCase is true
     *             3) Both CRS are decodeable and equalsIgnoreMetaData is true
     *
     *             Error situations are
     *
     *             1) One attribute has a srsName, the other not 2) a CRS is not decodeable
     *
     *             If we need a transformation, both geometries are transformd to WGS84
     */
    protected String transformOnDemand(GeometryAttribute array[]) throws GeoXACMLException {
        GeometryAttribute attr1 = array[0];
        GeometryAttribute attr2 = array[1];

        if (attr1.getSrsName() == null && attr2.getSrsName() == null)
            return null;

        if ((attr1.getSrsName() == null && attr2.getSrsName() != null)
                || (attr1.getSrsName() != null && attr2.getSrsName() == null)) {
            throw new GeoXACMLException("Missing srsName");
        }

        if (attr1.getSrsName().equalsIgnoreCase(attr2.getSrsName()))
            return attr1.getSrsName();

        CoordinateReferenceSystem[] crsArray = new CoordinateReferenceSystem[2];
        crsArray[0] = decodeCRS(array[0].getSrsName());
        crsArray[1] = decodeCRS(array[1].getSrsName());

        for (int i = 0; i < crsArray.length; i++) { // check if not null
            if (crsArray[i] == null)
                throw new GeoXACMLException("Cannod decode " + array[i].getSrsName());
        }

        if (CRS.equalsIgnoreMetadata(crsArray[0], crsArray[1])) // CRS are compatible
            return array[0].getSrsName();

        try {
            for (int i = 0; i < array.length; i++) {
                Geometry newGeom = transformToCommonCRS(array[i].getGeometry(), array[i]
                        .getSrsName(), crsArray[i]);
                if (newGeom != array[i].getGeometry()) { // geometry changed
                    GeometryAttribute newGeomAttr = new GeometryAttribute(newGeom, COMMON_CRS_NAME,
                            array[i].getGid(), array[i].getGmlVersion(), array[i].getType()
                                    .toString());
                    newGeomAttr.setSrsDimension(array[i].getSrsDimension());
                    array[i] = newGeomAttr;
                }
            }
        } catch (Exception e) {
            throw new GeoXACMLException(e);
        }
        return COMMON_CRS_NAME;

    }

    /**
     * @param g
     * @param srsName
     * @param sourceCRS
     * @return
     * @throws GeoXACMLException
     *
     *             Transformation of a geomtry to WGS84
     *
     *             No transformation in the following situations
     *
     *             1) the srsName equalsIgnoreCase with EPSG:4326 is true 2) equalsIgnorMetaData
     *             returns true
     */
    protected Geometry transformToCommonCRS(Geometry g, String srsName,
            CoordinateReferenceSystem sourceCRS) throws GeoXACMLException {

        try {
            if (COMMON_CRS == null) {
                synchronized (COMMON_CRS_NAME) {
                    COMMON_CRS = CRS.decode(COMMON_CRS_NAME, true);
                }
            }

            if (COMMON_CRS_NAME.equalsIgnoreCase(srsName))
                return g;

            if (CRS.equalsIgnoreMetadata(sourceCRS, COMMON_CRS))
                return g;

            MathTransform transform = CRS.findMathTransform(sourceCRS, COMMON_CRS);
            return JTS.transform(g, transform);
        } catch (Exception e) {
            throw new GeoXACMLException(e);
        }
    }

    /**
     * @param t
     *            a Throwable
     * @return an EvaluationResult indicating a processing error
     */
    protected EvaluationResult exceptionError(Throwable t) {

        Logger log = Logger.getLogger(this.getClass().getName());
        log.log(Level.SEVERE, t.getMessage(), t);

        List<String> codeList = new ArrayList<String>();
        codeList.add(Status.STATUS_PROCESSING_ERROR);
        return new EvaluationResult(new Status(codeList, t.getLocalizedMessage()));
    }

    /**
     * @param srsName
     * @return CoordinateRefernceSystem
     * @throws GeoXACMLException
     *
     *             try to decode the value of the GML srsName attribute
     */
    protected CoordinateReferenceSystem decodeCRS(String srsName) throws GeoXACMLException {

        URI srs = null;

        try {
            srs = new URI(srsName);
        } catch (URISyntaxException e) { // failed, continue on
        }

        if (srs != null) {
            // TODO: JD, this is a hack until GEOT-1136 has been resolved
            if ("http".equals(srs.getScheme()) && "www.opengis.net".equals(srs.getAuthority())
                    && "/gml/srs/epsg.xml".equals(srs.getPath()) && (srs.getFragment() != null)) {
                try {
                    return CRS.decode("EPSG:" + srs.getFragment(), true);
                } catch (Exception e) {
                    // failed, try as straight up uri
                    try {
                        return CRS.decode(srs.toString(), true);
                    } catch (Exception e1) {
                        // failed again, do nothing ,should fail below as well
                    }
                }
            }
        }

        try {
            return CRS.decode(srsName, true);
        } catch (NoSuchAuthorityCodeException e) {
            // HACK HACK HACK!: remove when
            // http://jira.codehaus.org/browse/GEOT-1659 is fixed

            if (srsName.toUpperCase().startsWith("URN")) {
                String code = srsName.substring(srsName.lastIndexOf(":") + 1);
                try {
                    return CRS.decode("EPSG:" + code, true);
                } catch (Exception e1) {
                    throw new GeoXACMLException("Could not create crs: " + srs, e);
                }
            }
        } catch (FactoryException e) {
            throw new GeoXACMLException("Could not create crs: " + srs, e);
        }

        return null;
    }

}
TOP

Related Classes of org.geotools.xacml.geoxacml.cond.GeoXACMLFunctionBase

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.