org.apache.openaz.xacml.util.XACMLProperties.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.openaz.xacml.util.XACMLProperties.java

Source

/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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.apache.openaz.xacml.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.common.base.Splitter;

/**
 * XACMLProperties is a wrapper around a <code>Properties</code> object loaded from a standard location for
 * XACML properties.
 */
public class XACMLProperties {
    private static final Log logger = LogFactory.getLog(XACMLProperties.class);

    public static final String XACML_PROPERTIES_NAME = "xacml.properties";
    public static final String XACML_PROPERTIES_FILE = System.getProperty("java.home") + File.separator + "lib"
            + File.separator + XACML_PROPERTIES_NAME;

    public static final String PROP_DATATYPEFACTORY = "xacml.dataTypeFactory";
    public static final String PROP_PDPENGINEFACTORY = "xacml.pdpEngineFactory";
    public static final String PROP_PEPENGINEFACTORY = "xacml.pepEngineFactory";
    public static final String PROP_PIPFINDERFACTORY = "xacml.pipFinderFactory";
    public static final String PROP_TRACEENGINEFACTORY = "xacml.traceEngineFactory";

    public static final String PROP_ROOTPOLICIES = "xacml.rootPolicies";
    public static final String PROP_REFERENCEDPOLICIES = "xacml.referencedPolicies";

    public static final String PROP_PDP_BEHAVIOR = "xacml.pdp.behavior";
    public static final String PROP_PIP_ENGINES = "xacml.pip.engines";

    // Alternative types of PAP Engine
    public static final String PROP_PAP_PAPENGINEFACTORY = "xacml.PAP.papEngineFactory";
    public static final String PROP_AC_PAPENGINEFACTORY = "xacml.AC.papEngineFactory";

    private static volatile Properties properties = new Properties();
    private static boolean needCache = true;

    private static File getPropertiesFile() {
        String propertiesFileName = System.getProperty(XACML_PROPERTIES_NAME);
        if (propertiesFileName == null) {
            propertiesFileName = XACML_PROPERTIES_FILE;
        }
        return new File(propertiesFileName);
    }

    protected XACMLProperties() {
    }

    public static Properties getProperties() throws IOException {
        if (needCache) {
            synchronized (properties) {
                if (needCache) {
                    File fileProperties = getPropertiesFile();
                    if (fileProperties.exists() && fileProperties.canRead()) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Loading properties from " + fileProperties.getAbsolutePath());
                        }
                        try (InputStream is = new FileInputStream(fileProperties)) {
                            properties.load(is);
                        }
                    } else {
                        logger.warn("Properties file " + fileProperties.getAbsolutePath() + " cannot be read.");
                    }
                    needCache = false;
                }
            }
        }
        return properties;
    }

    public static void reloadProperties() {
        synchronized (properties) {
            properties = new Properties();
            needCache = true;
        }
    }

    public static String getProperty(String propertyName, String defaultValue) {
        String value = System.getProperty(propertyName);
        if (value == null) {
            Properties properties = null;
            try {
                properties = getProperties();
                value = properties.getProperty(propertyName);
            } catch (IOException ex) {
                logger.debug("Error getting property: " + propertyName, ex);
            }
        }
        return value == null ? defaultValue : value;
    }

    public static void setProperty(String propertyName, String propertyValue) {
        try {
            getProperties().setProperty(propertyName, propertyValue);
        } catch (IOException ex) {
            logger.debug("Error setting property: " + propertyName, ex);
        }
    }

    public static String getProperty(String propertyName) {
        return getProperty(propertyName, null);
    }

    /**
     * Get the policy-related properties from the given set of properties. These may or may not include ".url"
     * entries for each policy. The caller determines whether it should include them or not and sets checkURLs
     * appropriately. If checkURLs is false and there are ".url" entries, they are put into the result set
     * anyway.
     *
     * @param current
     * @param checkURLs
     * @return
     * @throws Exception
     */
    public static Properties getPolicyProperties(Properties current, boolean checkURLs) throws Exception {
        Properties props = new Properties();
        String[] lists = new String[2];
        lists[0] = current.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
        lists[1] = current.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
        // require that PROP_ROOTPOLICIES exist, even when it is empty
        if (lists[0] != null) {
            props.setProperty(XACMLProperties.PROP_ROOTPOLICIES, lists[0]);
        } else {
            logger.error("Missing property: " + XACMLProperties.PROP_ROOTPOLICIES);
            throw new Exception("Missing property: " + XACMLProperties.PROP_ROOTPOLICIES);
        }
        // require that PROP_REFERENCEDPOLICIES exist, even when it is empty
        if (lists[1] != null) {
            props.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, lists[1]);
        } else {
            logger.error("Missing property: " + XACMLProperties.PROP_REFERENCEDPOLICIES);
            throw new Exception("Missing property: " + XACMLProperties.PROP_REFERENCEDPOLICIES);
        }
        Set<Object> keys = current.keySet();
        for (String list : lists) {
            if (list == null || list.length() == 0) {
                continue;
            }
            Iterable<String> policies = Splitter.on(',').trimResults().omitEmptyStrings().split(list);
            if (policies == null) {
                continue;
            }
            for (String policy : policies) {
                for (Object key : keys) {
                    if (key.toString().startsWith(policy)) {
                        props.setProperty(key.toString(), current.getProperty(key.toString()));
                    }
                }
                if (checkURLs) {
                    // every policy must have a ".url" property
                    String urlString = (String) props.get(policy + ".url");
                    if (urlString == null) {
                        logger.error("Policy '" + policy + "' has no .url property");
                        throw new Exception("Policy '" + policy + "' has no .url property");
                    }
                    // the .url must be a valid URL
                    try {
                        // if this does not throw an exception the URL is ok
                        new URL(urlString);
                    } catch (MalformedURLException e) {
                        logger.error("Policy '" + policy + "' has bad .url property");
                        throw new Exception("Policy '" + policy + "' has bad .url property");
                    }
                }
            }
        }
        return props;
    }

    /**
     * Used only when we want just xacml.rootPolicies and xacml.referencedPolicies without any ".url" entries.
     *
     * @return
     * @throws Exception
     */
    public static Properties getPolicyProperties() throws Exception {
        return getPolicyProperties(XACMLProperties.getPolicyProperties(), false);
    }

    public static Set<String> getRootPolicyIDs(Properties props) {
        Set<String> ids = new HashSet<String>();
        String roots = props.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
        if (roots == null) {
            return ids;
        }
        Iterable<String> policies = Splitter.on(',').trimResults().omitEmptyStrings().split(roots);
        for (String id : policies) {
            ids.add(id);
        }
        return ids;
    }

    public static Set<String> getReferencedPolicyIDs(Properties props) {
        Set<String> ids = new HashSet<String>();
        String refs = props.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
        if (refs == null) {
            return ids;
        }
        Iterable<String> policies = Splitter.on(',').trimResults().omitEmptyStrings().split(refs);
        for (String id : policies) {
            ids.add(id);
        }
        return ids;
    }

    public static Set<String> getPolicyIDs(Properties props) {
        Set<String> ids = XACMLProperties.getRootPolicyIDs(props);
        ids.addAll(XACMLProperties.getReferencedPolicyIDs(props));
        return ids;
    }

    public static Properties getPipProperties(Properties current) throws Exception {
        Properties props = new Properties();
        String list = current.getProperty(XACMLProperties.PROP_PIP_ENGINES);
        // require that PROP_PIP_ENGINES exist, even when it is empty
        if (list != null) {
            props.setProperty(XACMLProperties.PROP_PIP_ENGINES, list);
        } else {
            throw new Exception("Missing property: " + XACMLProperties.PROP_PIP_ENGINES);
        }
        if (list == null || list.length() == 0) {
            return props;
        }
        Iterable<String> pips = Splitter.on(',').trimResults().omitEmptyStrings().split(list);
        if (pips == null) {
            return props;
        }
        Set<Object> keys = current.keySet();
        for (String pip : pips) {
            for (Object key : keys) {
                if (key.toString().startsWith(pip)) {
                    props.setProperty(key.toString(), current.getProperty(key.toString()));
                }
            }
        }
        return props;
    }

    public static Properties getPipProperties() throws Exception {
        return getPipProperties(XACMLProperties.getPipProperties());
    }
}