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

com.maxifier.mxcache.config.JaxbRule Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2014 Maxifier Ltd. All Rights Reserved.
 */
package com.maxifier.mxcache.config;

import com.maxifier.mxcache.DependencyTracking;
import com.maxifier.mxcache.Strategy;
import com.maxifier.mxcache.provider.CachingStrategy;
import com.maxifier.mxcache.resource.ResourceDependency;
import com.maxifier.mxcache.resource.TrackDependency;
import gnu.trove.map.hash.THashMap;
import gnu.trove.set.hash.THashSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author Alexander Kochurov ([email protected])
 */
class JaxbRule implements Rule {
    private static class PropertyValueImpl {
        boolean important;

        Object value;
    }

    private static final Logger logger = LoggerFactory.getLogger(JaxbRule.class);

    @XmlAttribute
    private boolean disabled;

    @XmlElement
    private Boolean disableCache;

    @XmlTransient
    private boolean disableCacheImportant;

    @XmlAttribute
    private boolean important;

    @XmlElement
    private DependencyTracking trackDependency = DependencyTracking.DEFAULT;

    @XmlTransient
    private boolean trackImportant;

    @XmlElement(name = "resourceDependency")
    private Set resourceDependencies;

    @XmlElement(name = "strategy")
    private String strategyClassName;

    @XmlElement(name = "cacheName")
    private String cacheName;

    @XmlTransient
    private boolean cacheNameImportant;

    @XmlTransient
    private Class strategy;

    @XmlTransient
    private boolean strategyImportant;

    @SuppressWarnings ({ "MismatchedQueryAndUpdateOfCollection" })
    @XmlElement (name = "property")
    private List properties;

    @XmlTransient
    private final Set ruleNames = new THashSet();

    @XmlTransient
    private final Map propertyMap = new THashMap();

    @Override
    public void override(Method method, String cacheName) {
        if (!cacheNameImportant && cacheName != null) {
            this.cacheName = cacheName;
        }
        if (!strategyImportant) {
            Strategy annotatedStrategy = method.getAnnotation(Strategy.class);
            if (annotatedStrategy != null) {
                strategy = annotatedStrategy.value();
            }
        }
        if (!trackImportant) {
            TrackDependency trackDependency = method.getAnnotation(TrackDependency.class);
            if (trackDependency != null) {
                this.trackDependency = trackDependency.value();
            }
        }
        ResourceDependency dependency = method.getAnnotation(ResourceDependency.class);
        if (dependency != null) {
            if (resourceDependencies == null) {
                resourceDependencies = new THashSet();
            }
            Collections.addAll(resourceDependencies, dependency.value());
        }
    }

    void override(JaxbRule rule) {
        overrideTrackDependency(rule);
        overrideDisableCache(rule);
        overrideStrategyClassName(rule);
        overrideCacheName(rule);
        overrideResourceDependencies(rule);
        overrideProperties(rule);
    }

    private void overrideResourceDependencies(JaxbRule rule) {
        if (rule.resourceDependencies != null) {
            if (resourceDependencies == null) {
                resourceDependencies = rule.resourceDependencies;
            } else {
                resourceDependencies.addAll(rule.resourceDependencies);
            }
        }
    }

    private void overrideTrackDependency(JaxbRule rule) {
        if (rule.trackDependency != DependencyTracking.DEFAULT && (!trackImportant || rule.important)) {
            trackDependency = rule.trackDependency;
            trackImportant = rule.important;
        }
    }

    private void overrideCacheName(JaxbRule rule) {
        if (rule.cacheName != null && (!cacheNameImportant || rule.important)) {
            cacheName = rule.cacheName;
            cacheNameImportant = rule.important;
        }
    }

    private void overrideStrategyClassName(JaxbRule rule) {
        if (rule.strategyClassName != null && (!strategyImportant || rule.important)) {
            strategyClassName = rule.strategyClassName;
            strategyImportant = rule.important;
        }
    }

    private void overrideDisableCache(JaxbRule rule) {
        if (rule.disableCache != null && (!disableCacheImportant || rule.important)) {
            disableCache = rule.disableCache;
            disableCacheImportant = rule.important;
        }
    }

    private void overrideProperties(JaxbRule rule) {
        if (rule.properties != null) {
            for (StrategyProperty property : rule.properties) {
                String name = property.getName();
                PropertyValueImpl oldProperty = propertyMap.get(name);

                boolean set;
                Object value = getValue(rule, property);
                if (oldProperty == null) {
                    oldProperty = new PropertyValueImpl();
                    propertyMap.put(name, oldProperty);
                    set = true;
                } else {
                    set = !oldProperty.important || rule.important;
                }
                if (set) {
                    oldProperty.important = rule.important;
                    oldProperty.value = value;
                }
            }
        }
    }

    private Object getValue(JaxbRule rule, StrategyProperty property) {
        List valueList = property.getValues();
        String stringValue = property.getValue();
        if (valueList != null) {
            if (stringValue != null) {
                valueList = new ArrayList(valueList);
                valueList.add(stringValue);
                logger.error("Invalid configuration for rule " + rule + ": value and values both exist " + property.getName());
            }
            return valueList;
        }
        if (stringValue != null) {
            return stringValue;
        }
        logger.error("Invalid configuration for rule " + rule + ": empty property " + property.getName());
        return null;
    }

    @Override
    public Object getProperty(String name) {
        PropertyValueImpl value = propertyMap.get(name);
        return value == null ? null : value.value;
    }

    @Override
    public boolean isImportantProperty(String name) {
        PropertyValueImpl value = propertyMap.get(name);
        return value != null && value.important;
    }

    @Override
    public DependencyTracking getTrackDependency() {
        return trackDependency;
    }

    @Override
    public Set getResourceDependencies() {
        return resourceDependencies == null ? Collections.emptySet() : resourceDependencies;
    }

    @Override
    public Set getRuleNames() {
        return ruleNames;
    }

    void addRuleName(String name) {
        ruleNames.add(name);
    }

    @Override
    public Class getStrategy() {
        if (strategy != null) {
            return strategy;
        }
        if (strategyClassName == null) {
            return null;
        }
        try {
            //noinspection unchecked
            return (Class) Class.forName(strategyClassName);
        } catch (ClassNotFoundException c) {
            logger.error("Invalid configuration: unknown strategy class " + strategyClassName);
            return null;
        }
    }

    @Override
    public String getCacheName() {
        return cacheName;
    }

    @Override
    public boolean getDisableCache() {
        return disableCache != null && disableCache;
    }

    public String getName() {
        return getRuleNames().toString();
    }

    @Override
    public String toString() {
        return "rule:" + getName();
    }

    public boolean isDisabled() {
        return disabled;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy