All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.att.research.xacml.std.pip.engines.csv.XacmlCSVEngine Maven / Gradle / Ivy

There is a newer version: 2.2.0
Show newest version
/*
 *
 *          Copyright (c) 2013,2019  AT&T Knowledge Ventures
 *                     SPDX-License-Identifier: MIT
 */

package com.att.research.xacml.std.pip.engines.csv;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.att.research.xacml.api.Attribute;
import com.att.research.xacml.api.AttributeValue;
import com.att.research.xacml.api.DataType;
import com.att.research.xacml.api.DataTypeException;
import com.att.research.xacml.api.DataTypeFactory;
import com.att.research.xacml.api.Identifier;
import com.att.research.xacml.api.pip.PIPException;
import com.att.research.xacml.api.pip.PIPFinder;
import com.att.research.xacml.api.pip.PIPRequest;
import com.att.research.xacml.api.pip.PIPResponse;
import com.att.research.xacml.std.IdentifierImpl;
import com.att.research.xacml.std.StdMutableAttribute;
import com.att.research.xacml.std.pip.StdPIPResponse;
import com.att.research.xacml.std.pip.engines.ConfigurableEngine;
import com.att.research.xacml.util.FactoryException;

/**
 * CSVPIPEngine implements the {@link com.att.research.xacml.api.pip.PIPFinder} interface to find attributes
 * loaded from a text file containing the following fields:
 * 	category-id,attribute-id,datatype-id,issuer,value
 * 
 * @author car
 * @version $Revision: 1.1 $
 */
public class XacmlCSVEngine implements ConfigurableEngine {
	public static final String PROP_DESCRIPTION	= ".description";
	public static final String PROP_FILE		= ".file";
	
	private static final Logger logger	= LoggerFactory.getLogger(XacmlCSVEngine.class);
	
	private String name;
	private String description;
	private Map cache	= new HashMap();
	private List listAttributes	= new ArrayList();
	private DataTypeFactory dataTypeFactory;
	
	protected DataTypeFactory getDataTypeFactory() throws FactoryException {
		if (this.dataTypeFactory == null) {
			this.dataTypeFactory	= DataTypeFactory.newInstance();
		}
		return this.dataTypeFactory;
	}
	
	protected static String generateKey(PIPRequest pipRequest) {
		StringBuilder stringBuilder	= new StringBuilder(pipRequest.getCategory().toString());
		stringBuilder.append('+');
		stringBuilder.append(pipRequest.getAttributeId().toString());
		stringBuilder.append('+');
		stringBuilder.append(pipRequest.getDataTypeId().toString());
		String issuer	= pipRequest.getIssuer();
		if (issuer != null) {
			stringBuilder.append('+');
			stringBuilder.append(issuer);
		}
		return stringBuilder.toString();
	}
	
	protected void store(String[] fields) throws FactoryException {
		DataTypeFactory thisDataTypeFactory	= this.getDataTypeFactory();
		Identifier identifierCategory		= new IdentifierImpl(fields[0]);
		Identifier identifierAttribute		= new IdentifierImpl(fields[1]);
		Identifier identifierDataType		= new IdentifierImpl(fields[2]);
		String issuer						= (fields.length == 5 ? fields[3] : null);
		String value						= fields[fields.length - 1];
		
		DataType dataType				= thisDataTypeFactory.getDataType(identifierDataType);
		if (dataType == null) {
			logger.error("Unknown data type " + identifierDataType.stringValue());
			return;
		}
		
		AttributeValue attributeValue	= null;
		try {
			attributeValue	= dataType.createAttributeValue(value);
		} catch (DataTypeException ex) {
			throw new FactoryException("DataTypeException creating AttributeValue", ex);
		}
		Attribute attribute					= new StdMutableAttribute(identifierCategory, identifierAttribute, attributeValue, issuer, false);
		this.listAttributes.add(attribute);
	}
	
	public XacmlCSVEngine() {
		
	}
	
	public void loadAttributes(File fileAttributes) throws IOException, ParseException, FactoryException {
		if (fileAttributes != null) {
			if (!fileAttributes.exists()) {
				throw new FileNotFoundException("Attributes file " + fileAttributes.getAbsolutePath() + " not found.");
			} else if (!fileAttributes.canRead()) {
				throw new IOException("Attributes file " + fileAttributes.getAbsolutePath() + " is not readable.");
			}
			
			try (BufferedReader bufferedReader	= new BufferedReader(new InputStreamReader(new FileInputStream(fileAttributes)))) {
				String line;
				while ((line = bufferedReader.readLine()) != null) {
					if (line.length() > 0) {
						String[] fields	= line.split("[|]",-1);
						if (fields.length < 4) {
							logger.warn("Not enough fields in record \"" + line + "\"");
							continue;
						}
						this.store(fields);
						
					}
				}
			}
		}
	}
	
	protected Attribute findAttribute(PIPRequest pipRequest) {
		Attribute attributeResult			= null;
		Iterator iterAttributes	= this.listAttributes.iterator();
		while ((attributeResult == null) && iterAttributes.hasNext()) {
			Attribute attributeTest	= iterAttributes.next();
			if (pipRequest.getCategory().equals(attributeTest.getCategory()) &&
				pipRequest.getAttributeId().equals(attributeTest.getAttributeId()) &&
				(pipRequest.getIssuer() == null || pipRequest.getIssuer().equals(attributeTest.getIssuer()))) {
				attributeResult	= attributeTest;
			}
		}
		return attributeResult;
	}

	@Override
	public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException {
		String pipRequestKey	= generateKey(pipRequest);
		PIPResponse pipResponse	= this.cache.get(pipRequestKey);
		if (pipResponse == null) {
			Attribute attributeMatch	= this.findAttribute(pipRequest);
			if (attributeMatch != null) {
				/*
				 * Iterate through the values and only return the ones that match the requested data type
				 */
				List> matchingValues	= new ArrayList>();
				Iterator> iterAttributeValues	= attributeMatch.getValues().iterator();
				while (iterAttributeValues.hasNext()) {
					AttributeValue attributeValue	= iterAttributeValues.next();
					if (pipRequest.getDataTypeId().equals(attributeValue.getDataTypeId())) {
						matchingValues.add(attributeValue);
					}
				}
				if (matchingValues.size() > 0) {
					Attribute attributeResponse	= new StdMutableAttribute(attributeMatch.getCategory(), attributeMatch.getAttributeId(), matchingValues, attributeMatch.getIssuer(), attributeMatch.getIncludeInResults());
					pipResponse					= new StdPIPResponse(attributeResponse);
					this.cache.put(pipRequestKey, pipResponse);
				}
			}
		}
		if (pipResponse == null) {
			return StdPIPResponse.PIP_RESPONSE_EMPTY;
		} else {
			return pipResponse;
		}
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public String getDescription() {
		return this.description;
	}

	@Override
	public void configure(String id, Properties properties) throws PIPException {
		this.name	= id;
		this.description	= properties.getProperty(id + PROP_DESCRIPTION);
		if (this.description == null) {
			this.description	= "PIPEngine for the Conformance tests that loads attributes from a CSV file";
		}
		String pipFile		= properties.getProperty(id + PROP_FILE);
		if (pipFile != null) {
			try {
				this.loadAttributes(new File(pipFile));
			} catch (Exception ex) {
				logger.error("Exception loading PIP file " + pipFile, ex);
				throw new PIPException("Exception loading PIP file " + pipFile, ex);
			}
		}
	}

	@Override
	public Collection attributesRequired() {
		return Collections.emptyList();
	}

	@Override
	public Collection attributesProvided() {
		//
		// We could return the whole list of attributes
		//
		return Collections.emptyList();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy