package melcoe.xacml.pdp.finder.attribute; import java.net.URI; import java.util.HashSet; import java.util.Map; import java.util.Set; import melcoe.xacml.MelcoeXacmlException; import melcoe.xacml.pdp.finder.AttributeFinderConfigUtil; import melcoe.xacml.pdp.finder.AttributeFinderException; import melcoe.xacml.util.ContextUtil; import melcoe.xacml.util.RelationshipResolver; import org.apache.log4j.Logger; import com.sun.xacml.EvaluationCtx; import com.sun.xacml.attr.AttributeFactory; import com.sun.xacml.attr.AttributeValue; import com.sun.xacml.attr.BagAttribute; import com.sun.xacml.attr.StandardAttributeFactory; import com.sun.xacml.cond.EvaluationResult; import com.sun.xacml.finder.AttributeFinderModule; public class FedoraRIAttributeFinder extends AttributeFinderModule { private static final Logger log = Logger.getLogger(FedoraRIAttributeFinder.class); private AttributeFactory attributeFactory = null; private RelationshipResolver relationshipResolver = null; private Map<Integer, Set<String>> attributes = null; public FedoraRIAttributeFinder() { try { attributes = AttributeFinderConfigUtil.getAttributeFinderConfig(this .getClass().getName()); log .info("Initialised AttributeFinder:" + this.getClass().getName()); if (log.isDebugEnabled()) { log.debug("registering the following attributes: "); for (Integer k : attributes.keySet()) { for (String l : attributes.get(k)) { log.debug(k + ": " + l); } } } Map<String, String> resolverConfig = AttributeFinderConfigUtil.getResolverConfig(this.getClass() .getName()); if (log.isDebugEnabled()) { for (String s : resolverConfig.keySet()) { log.debug(s + ": " + resolverConfig.get(s)); } } relationshipResolver = ContextUtil.getInstance().getRelationshipResolver(); attributeFactory = StandardAttributeFactory.getFactory(); } catch (AttributeFinderException afe) { log.fatal("Attribute finder not initialised:" + this.getClass().getName()); } } /** * Returns true always because this module supports designators. * * @return true always */ @Override public boolean isDesignatorSupported() { return true; } /** * Returns a <code>Set</code> with a single <code>Integer</code> specifying * that environment attributes are supported by this module. * * @return a <code>Set</code> with * <code>AttributeDesignator.ENVIRONMENT_TARGET</code> included */ @Override public Set<Integer> getSupportedDesignatorTypes() { return attributes.keySet(); } /** * Used to get an attribute. If one of those values isn't being asked for, * or if the types are wrong, then an empty bag is returned. * * @param attributeType * the datatype of the attributes to find, which must be time, date, * or dateTime for this module to resolve a value * @param attributeId * the identifier of the attributes to find, which must be one of the * three ENVIRONMENT_* fields for this module to resolve a value * @param issuer * the issuer of the attributes, or null if unspecified * @param subjectCategory * the category of the attribute or null, which ignored since this * only handles non-subjects * @param context * the representation of the request data * @param designatorType * the type of designator, which must be ENVIRONMENT_TARGET for this * module to resolve a value * @return the result of attribute retrieval, which will be a bag with a * single attribute, an empty bag, or an error */ @Override public EvaluationResult findAttribute(URI attributeType, URI attributeId, URI issuer, URI subjectCategory, EvaluationCtx context, int designatorType) { String resourceId = context.getResourceId().encode(); if (log.isDebugEnabled()) { log.debug("RIAttributeFinder: [" + attributeType.toString() + "] " + attributeId + ", rid=" + resourceId); } if (resourceId == null || resourceId.equals("")) { return new EvaluationResult(BagAttribute .createEmptyBag(attributeType)); } // figure out which attribute we're looking for String attrName = attributeId.toString(); // we only know about registered attributes from config file if (!attributes.keySet().contains(new Integer(designatorType))) { if (log.isDebugEnabled()) { log.debug("Does not know about designatorType: " + designatorType); } return new EvaluationResult(BagAttribute .createEmptyBag(attributeType)); } Set<String> allowedAttributes = attributes.get(new Integer(designatorType)); if (!allowedAttributes.contains(attrName)) { if (log.isDebugEnabled()) { log.debug("Does not know about attribute: " + attrName); } return new EvaluationResult(BagAttribute .createEmptyBag(attributeType)); } EvaluationResult result = null; try { result = getEvaluationResult(resourceId, attrName, attributeType); } catch (Exception e) { log.error("Error finding attribute: " + e.getMessage(), e); return new EvaluationResult(BagAttribute .createEmptyBag(attributeType)); } return result; } private EvaluationResult getEvaluationResult(String pid, String attribute, URI type) throws AttributeFinderException { Map<String, Set<String>> relationships; try { relationships = relationshipResolver.getRelationships(pid); } catch (MelcoeXacmlException e) { throw new AttributeFinderException(e.getMessage(), e); } Set<String> results = relationships.get(attribute); if (results == null || results.size() == 0) { return new EvaluationResult(BagAttribute.createEmptyBag(type)); } Set<AttributeValue> bagValues = new HashSet<AttributeValue>(); for (String s : results) { AttributeValue attributeValue = null; try { attributeValue = attributeFactory.createValue(type, s); } catch (Exception e) { log.error("Error creating attribute: " + e.getMessage(), e); continue; } bagValues.add(attributeValue); if (log.isDebugEnabled()) { log.debug("AttributeValue found: [" + type.toASCIIString() + "] " + s); } } BagAttribute bag = new BagAttribute(type, bagValues); return new EvaluationResult(bag); } }