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

com.tacitknowledge.flip.properties.XmlPropertyReader Maven / Gradle / Ivy

The newest version!
/* Copyright 2012 Tacit Knowledge
*
* 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 com.tacitknowledge.flip.properties;

import com.tacitknowledge.flip.model.FeatureDescriptors;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;

import com.tacitknowledge.flip.model.FeatureDescriptor;

/**
 * The class which reads the feature descriptors from XML file. It caches them and 
 * periodically refreshes the cache. 
* The XML file should be of the following structure:
*
 * <features>
 *   <feature name="[name]" state="[overriding-state]">
 *     <rule state="[state-to-apply]">
 *       <condition context="[context]" name="[property]" operation="[operation]" value="[value-to-compare]" />
 *       ...
 *     </rule>
 *     ...
 *   </feature>
 *   ...
 * </features>
 * 
* *

* where: *

    *
  • [name] - is the feature name.
  • *
  • [overriding-state] - the state which is used. The rules are not processed.
  • *
  • [state-to-apply] - this state is applied if the conditions in the rule match.
  • *
  • [context] - the context where to find the [property]. If it is set to "_all" then * the property will be searched in all contexts available.
  • * *
  • [property] - the name of property from the context(s). The property could be a dotted expression * which will return the values of nested objects.
  • *
  • [operation] - the operation to apply to the value of property with value. Here could be the following operations:
    *
    *
    eq
    - checks for equality
    *
    ne
    - checks for inequality
    *
    lt
    - checks that property is less than value
    *
    le
    - checks that property is less or equals to value
    *
    gt
    - checks that property is greater than value
    *
    ge
    - checks that property is greater or equals to value
    *
    matches
    - checks that the regular expression passed as value matches the property value
    *
    not-matches
    - checks that the regular expression passed as value do not matches the property value
    *
    *
  • *
  • [value] - the value used to compare the property value using operator.
  • *
*

*

* The features, rules and conditions could be as many as you want. * The rules are applied sequentially as they are declared. The last rule should be without conditions * as a default rule. If none of conditions will match the last one will return the result. *

* * @author Serghei Soloviov */ @FlipProperty(priority = 100) public class XmlPropertyReader extends RefreshablePropertyReader { /** * The name of property whose value points to the XML file with configuration. */ public static final String CONFIG_PROPERTY = "flip.properties.xml.path"; /** * The property whose value points to XML file with configuration. */ public static final String CONFIG_FILE_NAME = "flip.properties.xml"; /** * Returns the stream with XML configuration file content. Firstly this * method looks up for a property {@link #CONFIG_PROPERTY} in properties passed * if there is no such property it looks up {@link #CONFIG_PROPERTY} property * in system properties and if here too the property was not found it looks * for the XML file in classpath by name {@code "flip.properties.xml"}. * * @param props the properties with configuration * @return the stream with XML file content. */ protected InputStream getConfigurationStream(final Properties props) { InputStream result = getConfigStreamFromProperties(props); if (result != null) { return result; } result = getConfigStreamFromProperties(System.getProperties()); if (result != null) { return result; } result = getClass().getClassLoader().getResourceAsStream(CONFIG_FILE_NAME); if (result != null) { return result; } return null; } /** * Looks up in the properties for {@link #CONFIG_PROPERTY} and returns the * stream of the XML file configuration. If the properties does not contains * such a property or the property points to an inexistent file returns {@code null}. * * @param props the properties where to look up for {@link #CONFIG_PROPERTY}. * @return the stream with XML file content. */ protected InputStream getConfigStreamFromProperties(final Properties props) { if (props == null) { return null; } try { final String path = props.getProperty(CONFIG_PROPERTY); if (path == null) { return null; } final File configFile = new File(path); if (!configFile.exists()) { return null; } return new FileInputStream(configFile); } catch (final IOException ex) { Logger.getLogger(XmlPropertyReader.class.getName()).log(Level.WARNING, null, ex); return null; } } /** * {@inheritDoc } */ @Override protected void readDescriptors() { try { final InputStream in = getConfigurationStream(getConfig()); if (in == null) { return; } final JAXBContext context = JAXBContext.newInstance(FeatureDescriptors.class); final Unmarshaller unmarshaller = context.createUnmarshaller(); final FeatureDescriptors descriptors = (FeatureDescriptors) unmarshaller .unmarshal(in); cache.clear(); if (descriptors != null && descriptors.getFeatures() != null) { for (final FeatureDescriptor descriptor : descriptors.getFeatures()) { cache.put(descriptor.getName(), descriptor); } } } catch (final JAXBException ex) { Logger.getLogger(XmlPropertyReader.class.getName()).log(Level.WARNING, null, ex); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy