/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2014 Geomatys. * * Licensed 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.constellation.xacml; import com.sun.xacml.Indenter; import com.sun.xacml.Obligation; import com.sun.xacml.ParsingException; import com.sun.xacml.ctx.ResponseCtx; import com.sun.xacml.ctx.Result; import com.sun.xacml.ctx.Status; import org.constellation.xacml.api.ResponseContext; import org.geotoolkit.xacml.xml.context.ObjectFactory; import org.geotoolkit.xacml.xml.context.ResultType; import org.geotoolkit.xacml.xml.context.StatusCodeType; import org.geotoolkit.xacml.xml.context.StatusType; import org.geotoolkit.xacml.xml.policy.EffectType; import org.geotoolkit.xacml.xml.policy.ObligationType; import org.geotoolkit.xacml.xml.policy.ObligationsType; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Implementation of the ResponseContext interface * @author Anil.Saldhana@redhat.com * @since Jul 6, 2007 * @version $Revision$ */ public class CstlResponseContext implements ResponseContext { private final Map<XACMLConstants, Object> map = new HashMap<XACMLConstants, Object>(); private Node documentElement = null; /** * @see ContextMapOp#get */ @Override public Object get(final XACMLConstants key) { return map.get(key); } /** * @see ContextMapOp#set */ @Override public void set(final XACMLConstants key, final Object obj) { map.put(key, obj); } /** * @see ResponseContext#getDecision() */ @Override public int getDecision() { final int decision = XACMLConstants.DECISION_DENY; final ResponseCtx response = (ResponseCtx) map.get(XACMLConstants.RESPONSE_CTX); if (response == null) { return decision; } final Set<Result> results = response.getResults(); if (results == null || results.isEmpty()) { return decision; } final Result res = results.iterator().next(); if (res == null) { return decision; } return res.getDecision(); } /** * @see ResponseContext#getResult() */ @Override public ResultType getResult() { final ObjectFactory objectFactory = new ObjectFactory(); final ResultType resultType = objectFactory.createResultType(); final ResponseCtx response = (ResponseCtx) map.get(XACMLConstants.RESPONSE_CTX); if (response == null) { return resultType; } final Set<Result> results = response.getResults(); if (results == null || results.isEmpty()) { return resultType; } //Resource ID final Result result = (Result) results.iterator().next(); if (result == null) { return resultType; } resultType.setResourceId(result.getResource()); //Status final Status status = result.getStatus(); final StatusType statusType = objectFactory.createStatusType(); final StatusCodeType statusCodeType = objectFactory.createStatusCodeType(); statusCodeType.setValue(status.getMessage()); statusType.setStatusCode(statusCodeType); //Obligations final Set<Obligation> obligationsSet = result.getObligations(); if (obligationsSet == null) { return resultType; } for (Obligation obl : obligationsSet) { final ObligationType obType = new ObligationType(); obType.setObligationId(obl.getId().toASCIIString()); obType.setFulfillOn(EffectType.fromValue(Result.DECISIONS[obl.getFulfillOn()])); final ObligationsType obligationsType = new ObligationsType(); obligationsType.getObligation().add(obType); resultType.setObligations(obligationsType); } return resultType; } /** * @see ResponseContext#getDocumentElement() */ @Override public Node getDocumentElement() { return documentElement; } /** * @see ResponseContext#marshall(OutputStream) */ @Override public void marshall(final OutputStream os) throws IOException { final ResponseCtx storedResponse = (ResponseCtx) get(XACMLConstants.RESPONSE_CTX); if (storedResponse != null) { storedResponse.encode(os, new Indenter(0)); } } /** * @see ResponseContext#readResponse(InputStream) */ @Override public void readResponse(final InputStream is) throws IOException { readResponse(getResponse(is)); } /** * @see ResponseContext#readResponse(Node) */ @Override public void readResponse(final Node node) throws IOException { if (node == null) { throw new IllegalArgumentException("node is null"); } documentElement = node; final ResponseCtx responseCtx; try { responseCtx = ResponseCtx.getInstance(node); set(XACMLConstants.RESPONSE_CTX, responseCtx); } catch (ParsingException e) { throw new IOException(e.getMessage()); } } private Node getResponse(final InputStream is) throws IOException { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); factory.setIgnoringComments(true); final Document doc; try { doc = factory.newDocumentBuilder().parse(is); } catch (ParserConfigurationException ex) { throw new IOException(ex.getMessage()); } catch (SAXException ex) { throw new IOException(ex.getMessage()); } NodeList nodes = doc.getElementsByTagNameNS(XACMLConstants.CONTEXT_SCHEMA.name(), "Response"); if (nodes.getLength() == 0) { nodes = doc.getElementsByTagName("Response"); } return nodes.item(0); } }