001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Thomas Roger <troger@nuxeo.com>
016 */
017
018package org.nuxeo.ecm.localconf;
019
020import java.io.Serializable;
021import java.util.ArrayList;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.nuxeo.ecm.core.api.CoreSession;
029import org.nuxeo.ecm.core.api.DocumentModel;
030import org.nuxeo.ecm.core.api.DocumentRef;
031import org.nuxeo.ecm.core.api.PropertyException;
032import org.nuxeo.ecm.core.api.localconfiguration.AbstractLocalConfiguration;
033
034/**
035 * Default implementation of {@code SimpleConfiguration}.
036 *
037 * @see SimpleConfiguration
038 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
039 * @since 5.5
040 */
041public class SimpleConfigurationAdapter extends AbstractLocalConfiguration<SimpleConfiguration> implements
042        SimpleConfiguration {
043
044    private static final Log log = LogFactory.getLog(SimpleConfigurationAdapter.class);
045
046    protected DocumentModel detachedDocument;
047
048    protected Map<String, String> parameters;
049
050    public SimpleConfigurationAdapter(DocumentModel doc) {
051        loadFromDocument(doc);
052    }
053
054    protected void loadFromDocument(DocumentModel doc) {
055        detachedDocument = doc;
056        parameters = computeParametersFromDocument(doc);
057    }
058
059    @SuppressWarnings("unchecked")
060    protected Map<String, String> computeParametersFromDocument(DocumentModel doc) {
061        Map<String, String> parameters = new HashMap<String, String>();
062        try {
063            List<Map<String, String>> parametersFromDocument = (List<Map<String, String>>) doc.getPropertyValue(SIMPLE_CONFIGURATION_PARAMETERS_PROPERTY);
064            if (parametersFromDocument != null) {
065                for (Map<String, String> parameter : parametersFromDocument) {
066                    parameters.put(parameter.get(SIMPLE_CONFIGURATION_PARAMETER_KEY),
067                            parameter.get(SIMPLE_CONFIGURATION_PARAMETER_VALUE));
068                }
069            }
070        } catch (PropertyException e) {
071            log.warn("Unable to retrieve SimpleConfiguration parameters: " + e);
072            log.debug(e, e);
073        }
074        return parameters;
075    }
076
077    @Override
078    public String get(String key) {
079        return get(key, null);
080    }
081
082    @Override
083    public String get(String key, String defaultValue) {
084        String value = parameters.get(key);
085        return value != null ? value : defaultValue;
086    }
087
088    @Override
089    public String put(String key, String value) {
090        return parameters.put(key, value);
091    }
092
093    @Override
094    public void putAll(Map<String, String> parameters) {
095        this.parameters.putAll(parameters);
096    }
097
098    @Override
099    public DocumentRef getDocumentRef() {
100        return detachedDocument.getRef();
101    }
102
103    @Override
104    public boolean canMerge() {
105        return true;
106    }
107
108    @Override
109    public SimpleConfiguration merge(SimpleConfiguration other) {
110        if (other == null) {
111            return this;
112        }
113
114        SimpleConfigurationAdapter adapter = (SimpleConfigurationAdapter) other;
115        // set the document to the other SimpleConfiguration document to
116        // continue merging, if needed
117        detachedDocument = adapter.detachedDocument;
118
119        for (Map.Entry<String, String> otherParameter : adapter.parameters.entrySet()) {
120            // add only non-existing parameter
121            if (!parameters.containsKey(otherParameter.getKey())) {
122                parameters.put(otherParameter.getKey(), otherParameter.getValue());
123            }
124        }
125
126        return this;
127    }
128
129    @Override
130    public void save(CoreSession session) {
131        List<Map<String, String>> parametersForDocument = computeParametersForDocument(parameters);
132        detachedDocument.setPropertyValue(SIMPLE_CONFIGURATION_PARAMETERS_PROPERTY,
133                (Serializable) parametersForDocument);
134        DocumentModel doc = session.saveDocument(detachedDocument);
135        session.save();
136        loadFromDocument(doc);
137    }
138
139    protected List<Map<String, String>> computeParametersForDocument(Map<String, String> parameters) {
140        List<Map<String, String>> parametersForDocument = new ArrayList<Map<String, String>>();
141
142        for (Map.Entry<String, String> entry : parameters.entrySet()) {
143            Map<String, String> parameter = new HashMap<String, String>();
144            parameter.put(SIMPLE_CONFIGURATION_PARAMETER_KEY, entry.getKey());
145            parameter.put(SIMPLE_CONFIGURATION_PARAMETER_VALUE, entry.getValue());
146            parametersForDocument.add(parameter);
147        }
148
149        return parametersForDocument;
150    }
151
152}