net.xy.jcms.controller.configurations.ControllerConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for net.xy.jcms.controller.configurations.ControllerConfiguration.java

Source

/**
 * This file is part of XY.JCms, Copyright 2010 (C) Xyan Kruse, Xyan@gmx.net, Xyan.kilu.de
 * 
 * XY.JCms is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 * 
 * XY.JCms is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with XY.JCms. If not, see
 * <http://www.gnu.org/licenses/>.
 */
package net.xy.jcms.controller.configurations;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;

import net.xy.jcms.persistence.usecase.ConfigurationDTO;
import net.xy.jcms.shared.IController;

/**
 * configures the controller sectionwise and global. has an internal structure
 * of global space, controller specific
 * spaces and within controller instructions.
 * 
 * @author Xyan
 * 
 */
public class ControllerConfiguration extends Configuration<Map<String, Map<String, Object>>> {
    /**
     * gloabl type constant for this type
     */
    public static final ConfigurationType TYPE = ConfigurationType.ControllerConfiguration;

    /**
     * default
     * 
     * @param configurationValue
     */
    public ControllerConfiguration(final Map<String, Map<String, Object>> configurationValue) {
        super(TYPE, configurationValue);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public ControllerConfiguration mergeConfiguration(final Map<String, Map<String, Object>> otherConfig) {
        // controller section got separately merged
        final Map<String, Map<String, Object>> own = new HashMap<String, Map<String, Object>>(
                getConfigurationValue());
        for (final Entry<String, Map<String, Object>> ctrSec : otherConfig.entrySet()) {
            final String ctrlName = ctrSec.getKey();
            if (!own.containsKey(ctrlName)) {
                // ctrl config don't exist simply add
                own.put(ctrSec.getKey(), ctrSec.getValue());
                continue;
            }
            // else process ctrl config
            for (final Entry<String, Object> ctrItem : ctrSec.getValue().entrySet()) {
                // object can be an simple value or an list in case of
                // instructions
                if (!List.class.isInstance(ctrItem.getValue())) {
                    // simple overwrite
                    own.get(ctrlName).put(ctrItem.getKey(), ctrItem.getValue());
                    continue;
                }
                // when list append, warning two different listtypes cant be
                // merged
                final List otherList = (List) ctrItem.getValue();
                final Object thisValue = own.get(ctrlName).get(ctrItem.getKey());
                // two possibilities, own value is a list or not
                if (List.class.isInstance(thisValue)) {
                    ((List) thisValue).addAll(otherList);
                } else {
                    // overwrite
                    own.get(ctrlName).put(ctrItem.getKey(), ctrItem.getValue());
                }
            }
        }
        return new ControllerConfiguration(own);
    }

    @Override
    public ControllerConfiguration mergeConfiguration(
            final Configuration<Map<String, Map<String, Object>>> otherConfig) {
        return mergeConfiguration(otherConfig.getConfigurationValue());
    }

    /**
     * gets the globals
     * 
     * @return never null
     */
    public Map<String, Object> getGlobals() {
        if (!getConfigurationValue().containsKey(GLOBAL_CONFIG)) {
            getConfigurationValue().put(GLOBAL_CONFIG, new HashMap<String, Object>());
        }
        return getConfigurationValue().get(GLOBAL_CONFIG);
    }

    /**
     * gets an controller class associated config map
     * 
     * @param clazz
     * @return never null instead it creates an config for this controller
     */
    public Map<String, Object> getControllerConfig(final Class<? extends IController> clazz) {
        if (!IController.class.isAssignableFrom(clazz)) {
            throw new IllegalArgumentException("Obmitted class is no controller");
        }
        final String ctrlName = clazz.getSimpleName();
        if (!getConfigurationValue().containsKey(ctrlName)) {
            getConfigurationValue().put(ctrlName, new HashMap<String, Object>());
        }
        return getConfigurationValue().get(ctrlName);
    }

    @Override
    public int hashCode() {
        return getConfigurationValue().hashCode();
    }

    @Override
    public boolean equals(final Object object) {
        return getConfigurationValue().equals(object);
    }

    /**
     * global config identifier
     */
    public static final String GLOBAL_CONFIG = "GLOBAL";

    /**
     * parses an string to an controller goniguration each controller gets the
     * global and its all other configuration.
     * 
     * @param in
     * @return value
     */
    @SuppressWarnings("unchecked")
    public static Configuration<?> initByString(final String in) {
        final Map<String, Map<String, Object>> config = new HashMap<String, Map<String, Object>>();
        final String[] lines = in.split("\n");
        for (int i = 0; i < lines.length; i++) {
            final String line = lines[i].trim();
            if (StringUtils.isBlank(line) || line.startsWith("#")) {
                continue;
            }
            if (line.matches("^[A-Z]{1}[a-zA-Z0-9]+\\{$")) {
                // start controller section
                final String controllerName = line.substring(0, line.length() - 1);
                // forward to next line until } reached
                i++;
                if (!config.containsKey(controllerName)) {
                    config.put(controllerName, new LinkedHashMap<String, Object>());
                }
                final Map<String, Object> ctrlConfig = config.get(controllerName);
                for (; i < lines.length; i++) {
                    final String ctrlLine = lines[i].trim();
                    if (ctrlLine.contentEquals("}")) {
                        break;
                    }
                    if (StringUtils.isBlank(ctrlLine) || ctrlLine.startsWith("#")) {
                        continue;
                    }

                    if (ctrlLine.matches("^[a-zA-Z0-9.]+\\{$")) {
                        // begin of an controller config clustering
                        final String subSectionName = ctrlLine.substring(0, ctrlLine.length() - 1);
                        // forward to next line until } reached
                        i++;
                        final Object oldValue = ctrlConfig.get(subSectionName);
                        if (!List.class.isInstance(oldValue)) {
                            ctrlConfig.put(subSectionName, new LinkedList<Map<String, Object>>());
                            if (oldValue != null) {
                                final HashMap<String, Object> old = new HashMap<String, Object>();
                                old.put(subSectionName, oldValue);
                                ((List<Map<String, Object>>) ctrlConfig.get(subSectionName)).add(old);
                            }
                        }
                        final List<Map<String, Object>> subSections = (List<Map<String, Object>>) ctrlConfig
                                .get(subSectionName);
                        final Map<String, Object> subParam = new LinkedHashMap<String, Object>();
                        for (; i < lines.length; i++) {
                            final String subSec = lines[i].trim();
                            if (subSec.contentEquals("}")) {
                                break;
                            }
                            if (StringUtils.isBlank(subSec) || subSec.startsWith("#")) {
                                continue;
                            }
                            addLine(subSec, subParam);
                        }
                        if (!subParam.isEmpty()) {
                            subSections.add(subParam);
                        }
                    } else if (ctrlLine.contentEquals("}")) {
                        throw new IllegalArgumentException(
                                "There are unmatching controller subsection parentheses at line " + i + ".");
                    } else {
                        // simple controller config pair key = val
                        addLine(ctrlLine, ctrlConfig);
                    }
                }
            } else if (line.contentEquals("}")) {
                throw new IllegalArgumentException(
                        "There are global unmatching subsection parentheses at line " + i + ".");
            } else {
                // fill in globals section
                if (!config.containsKey(GLOBAL_CONFIG)) {
                    config.put(GLOBAL_CONFIG, new HashMap<String, Object>());
                }
                final Map<String, Object> global = config.get(GLOBAL_CONFIG);
                addLine(line, global);
            }
        }
        return new ControllerConfiguration(config);
    }

    /**
     * helper function which proccesses multiple line patterns
     * 
     * @param line
     * @param map
     */
    private static void addLine(final String line, final Map<String, Object> map) {
        if (line.contains("=")) {
            // asignment pattern
            final String[] values = line.split("=", 2);
            map.put(values[0].trim(), values[1].trim());
        } else {
            // flag pattern
            map.put(line.trim(), "true");
        }
    }

    /**
     * method to convert this config back to an string
     * 
     * @return dto
     */
    public ConfigurationDTO toDTO() {
        final ConfigurationDTO ret = new ConfigurationDTO();
        ret.setConfigurationType(TYPE);
        final StringBuilder conf = new StringBuilder();
        for (final Entry<String, Map<String, Object>> section : getConfigurationValue().entrySet()) {
            if (section.getKey().equals(GLOBAL_CONFIG)) {
                for (final Entry<String, Object> global : section.getValue().entrySet()) {
                    conf.append("\t").append(global.getKey()).append(" = ").append(global.getValue()).append("\n");
                }
            } else {
                conf.append(section.getKey()).append("{\n");
                for (final Entry<String, Object> ctrlVal : section.getValue().entrySet()) {
                    if (ctrlVal.getValue() instanceof List) {
                        // instructionlist
                        @SuppressWarnings("rawtypes")
                        final List inst = (List) ctrlVal.getValue();
                        for (final Object instItem : inst) {
                            conf.append("\t").append(ctrlVal.getKey()).append("{\n");
                            if (instItem instanceof Map) {
                                @SuppressWarnings("rawtypes")
                                final Map<?, ?> instMap = (Map) instItem;
                                for (final Entry<?, ?> entry : instMap.entrySet()) {
                                    conf.append("\t\t").append(entry.getKey()).append(" = ")
                                            .append(entry.getValue()).append("\n");
                                }
                            } else {
                                conf.append("\t\t").append(instItem).append("\n");
                            }
                            conf.append("\t}\n");
                        }
                    } else {
                        conf.append("\t").append(ctrlVal.getKey()).append(" = ").append(ctrlVal.getValue())
                                .append("\n");
                    }
                }
                conf.append("}\n");
            }
        }
        ret.setContent(conf.toString());
        return ret;
    }
}