/* * File: FieldSearchResultHandler.java * * Copyright 2007 Macquarie E-Learning Centre Of Excellence * * 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 melcoe.fedora.pep.ws.operations; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import melcoe.fedora.pep.PEPException; import melcoe.xacml.MelcoeXacmlException; import melcoe.xacml.util.ContextUtil; import org.apache.axis.MessageContext; import org.apache.axis.message.RPCParam; import org.apache.log4j.Logger; import com.sun.xacml.attr.AnyURIAttribute; import com.sun.xacml.attr.AttributeValue; import com.sun.xacml.attr.StringAttribute; import com.sun.xacml.ctx.RequestCtx; import com.sun.xacml.ctx.ResponseCtx; import com.sun.xacml.ctx.Result; import com.sun.xacml.ctx.Status; import fedora.common.Constants; import fedora.server.types.gen.FieldSearchResult; import fedora.server.types.gen.ObjectFields; /** * This class handles the filtering of search results for both the findObjects * and resumeFindObjects operations and is called by each of them. * * @author nishen@melcoe.mq.edu.au */ public class FieldSearchResultHandler extends AbstractOperationHandler { private static Logger log = Logger.getLogger(FieldSearchResultHandler.class.getName()); private final ContextUtil contextUtil = new ContextUtil(); /** * Default constructor. * * @throws PEPException */ public FieldSearchResultHandler() throws PEPException { super(); } /** * Removes non-permissable objects from the result list. * * @param context * the message context * @param result * the search result object * @return the new search result object without non-permissable items * @throws PEPException */ public FieldSearchResult filter(MessageContext context, FieldSearchResult result) throws PEPException { ObjectFields[] objs = result.getResultList(); List<String> requests = new ArrayList<String>(); Map<String, ObjectFields> objects = new HashMap<String, ObjectFields>(); if (objs.length == 0) { return result; } for (ObjectFields o : objs) { if (log.isDebugEnabled()) { log.debug("Checking: " + o.getPid()); } Map<URI, AttributeValue> actions = new HashMap<URI, AttributeValue>(); Map<URI, AttributeValue> resAttr = new HashMap<URI, AttributeValue>(); String pid = o.getPid(); if (pid != null && !"".equals(pid)) { objects.put(pid, o); try { actions .put(Constants.ACTION.ID.getURI(), new StringAttribute(Constants.ACTION.LIST_OBJECT_IN_FIELD_SEARCH_RESULTS .getURI().toASCIIString())); resAttr.put(Constants.OBJECT.PID.getURI(), new StringAttribute(pid)); resAttr.put(new URI(XACML_RESOURCE_ID), new AnyURIAttribute(new URI(pid))); RequestCtx req = getContextHandler() .buildRequest(getSubjects(context), actions, resAttr, getEnvironment(context)); requests.add(contextUtil.makeRequestCtx(req)); } catch (Exception e) { log.error(e.getMessage(), e); throw new OperationHandlerException(e.getMessage(), e); } } } String response = getContextHandler().evaluateBatch(requests .toArray(new String[requests.size()])); ResponseCtx resCtx; try { resCtx = contextUtil.makeResponseCtx(response); } catch (MelcoeXacmlException e) { throw new PEPException(e); } @SuppressWarnings("unchecked") Set<Result> results = resCtx.getResults(); List<ObjectFields> resultObjects = new ArrayList<ObjectFields>(); for (Result r : results) { if (r.getResource() == null || "".equals(r.getResource())) { log .warn("This resource has no resource identifier in the xacml response results!"); } else if (log.isDebugEnabled()) { log.debug("Checking: " + r.getResource()); } String[] ridComponents = r.getResource().split("\\/"); String rid = ridComponents[ridComponents.length - 1]; if (r.getStatus().getCode().contains(Status.STATUS_OK) && r.getDecision() == Result.DECISION_PERMIT) { ObjectFields tmp = objects.get(rid); if (tmp != null) { resultObjects.add(tmp); if (log.isDebugEnabled()) { log.debug("Adding: " + r.getResource() + "[" + rid + "]"); } } else { log .warn("Not adding this object as no object found for this key: " + r.getResource() + "[" + rid + "]"); } } } result.setResultList(resultObjects .toArray(new ObjectFields[resultObjects.size()])); return result; } /* * (non-Javadoc) * @see * melcoe.fedora.pep.ws.operations.OperationHandler#handleRequest(org.apache * .axis.MessageContext) */ public RequestCtx handleRequest(MessageContext context) throws OperationHandlerException { RequestCtx req = null; Map<URI, AttributeValue> resAttr = new HashMap<URI, AttributeValue>(); Map<URI, AttributeValue> actions = new HashMap<URI, AttributeValue>(); try { resAttr.put(Constants.OBJECT.PID.getURI(), new StringAttribute("FedoraRepository")); resAttr.put(new URI(XACML_RESOURCE_ID), new AnyURIAttribute(new URI("FedoraRepository"))); actions.put(Constants.ACTION.ID.getURI(), new StringAttribute(Constants.ACTION.FIND_OBJECTS .getURI().toASCIIString())); actions.put(Constants.ACTION.API.getURI(), new StringAttribute(Constants.ACTION.APIA.getURI() .toASCIIString())); req = getContextHandler().buildRequest(getSubjects(context), actions, resAttr, getEnvironment(context)); } catch (Exception e) { log.error(e.getMessage(), e); throw new OperationHandlerException(e.getMessage(), e); } return req; } /* * (non-Javadoc) * @see * melcoe.fedora.pep.ws.operations.OperationHandler#handleResponse(org.apache * .axis.MessageContext) */ public RequestCtx handleResponse(MessageContext context) throws OperationHandlerException { try { FieldSearchResult result = (FieldSearchResult) getSOAPResponseObject(context); result = filter(context, result); RPCParam param = new RPCParam(context.getOperation().getReturnQName(), result); setSOAPResponseObject(context, param); } catch (Exception e) { log.error("Error filtering Objects", e); throw new OperationHandlerException("Error filtering Objects", e); } return null; } }