001/*
002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 * Contributors:
016 * Nuxeo - initial API and implementation
017 */
018
019package org.nuxeo.ecm.platform.types.localconfiguration;
020
021import static org.nuxeo.ecm.platform.types.localconfiguration.UITypesConfigurationConstants.UI_TYPES_CONFIGURATION_ALLOWED_TYPES_PROPERTY;
022import static org.nuxeo.ecm.platform.types.localconfiguration.UITypesConfigurationConstants.UI_TYPES_CONFIGURATION_DEFAULT_TYPE;
023import static org.nuxeo.ecm.platform.types.localconfiguration.UITypesConfigurationConstants.UI_TYPES_CONFIGURATION_DENIED_TYPES_PROPERTY;
024import static org.nuxeo.ecm.platform.types.localconfiguration.UITypesConfigurationConstants.UI_TYPES_CONFIGURATION_DENY_ALL_TYPES_PROPERTY;
025import static org.nuxeo.ecm.platform.types.localconfiguration.UITypesConfigurationConstants.UI_TYPES_DEFAULT_TYPE;
026
027import java.util.ArrayList;
028import java.util.Arrays;
029import java.util.Collections;
030import java.util.HashMap;
031import java.util.Iterator;
032import java.util.List;
033import java.util.Map;
034
035import org.apache.commons.logging.Log;
036import org.apache.commons.logging.LogFactory;
037import org.nuxeo.ecm.core.api.DocumentModel;
038import org.nuxeo.ecm.core.api.DocumentRef;
039import org.nuxeo.ecm.core.api.PropertyException;
040import org.nuxeo.ecm.core.api.localconfiguration.AbstractLocalConfiguration;
041import org.nuxeo.ecm.platform.types.SubType;
042
043/**
044 * Default implementation of {@code UITypesConfiguration}.
045 *
046 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
047 */
048public class UITypesConfigurationAdapter extends AbstractLocalConfiguration<UITypesConfiguration> implements
049        UITypesConfiguration {
050
051    private static final Log log = LogFactory.getLog(UITypesConfigurationAdapter.class);
052
053    protected DocumentRef documentRef;
054
055    protected List<String> allowedTypes;
056
057    protected List<String> deniedTypes;
058
059    protected boolean denyAllTypes;
060
061    protected boolean canMerge = true;
062
063    protected String defaultType;
064
065    public UITypesConfigurationAdapter(DocumentModel doc) {
066        documentRef = doc.getRef();
067        allowedTypes = getTypesList(doc, UI_TYPES_CONFIGURATION_ALLOWED_TYPES_PROPERTY);
068        deniedTypes = getTypesList(doc, UI_TYPES_CONFIGURATION_DENIED_TYPES_PROPERTY);
069        defaultType = getDefaultType(doc);
070
071        denyAllTypes = getDenyAllTypesProperty(doc);
072        if (denyAllTypes) {
073            canMerge = false;
074        }
075    }
076
077    protected List<String> getTypesList(DocumentModel doc, String property) {
078        String[] types;
079        try {
080            types = (String[]) doc.getPropertyValue(property);
081        } catch (PropertyException e) {
082            return Collections.emptyList();
083        }
084        if (types == null) {
085            return Collections.emptyList();
086        }
087        return Collections.unmodifiableList(Arrays.asList(types));
088    }
089
090    protected boolean getDenyAllTypesProperty(DocumentModel doc) {
091        try {
092            Boolean value = (Boolean) doc.getPropertyValue(UI_TYPES_CONFIGURATION_DENY_ALL_TYPES_PROPERTY);
093            return Boolean.TRUE.equals(value);
094        } catch (PropertyException e) {
095            return false;
096        }
097    }
098
099    protected String getDefaultType(DocumentModel doc) {
100        String value = UI_TYPES_DEFAULT_TYPE;
101        try {
102            value = (String) doc.getPropertyValue(UI_TYPES_CONFIGURATION_DEFAULT_TYPE);
103        } catch (PropertyException e) {
104            log.debug("can't get default type for:" + doc.getPathAsString(), e);
105        }
106        return value;
107    }
108
109    @Override
110    public List<String> getAllowedTypes() {
111        return allowedTypes;
112    }
113
114    @Override
115    public List<String> getDeniedTypes() {
116        return deniedTypes;
117    }
118
119    @Override
120    public boolean denyAllTypes() {
121        return denyAllTypes;
122    }
123
124    @Override
125    public DocumentRef getDocumentRef() {
126        return documentRef;
127    }
128
129    @Override
130    public boolean canMerge() {
131        return canMerge;
132    }
133
134    @Override
135    public UITypesConfiguration merge(UITypesConfiguration other) {
136        if (other == null) {
137            return this;
138        }
139
140        // set the documentRef to the other UITypesConfiguration to continue
141        // merging, if needed
142        documentRef = other.getDocumentRef();
143
144        List<String> deniedTypes = new ArrayList<String>(this.deniedTypes);
145        deniedTypes.addAll(other.getDeniedTypes());
146        this.deniedTypes = Collections.unmodifiableList(deniedTypes);
147
148        denyAllTypes = other.denyAllTypes();
149        if (denyAllTypes) {
150            canMerge = false;
151        }
152
153        return this;
154    }
155
156    @Override
157    public Map<String, SubType> filterSubTypes(Map<String, SubType> allowedSubTypes) {
158        if (denyAllTypes()) {
159            return Collections.emptyMap();
160        }
161
162        List<String> allowedTypes = getAllowedTypes();
163        List<String> deniedTypes = getDeniedTypes();
164        if (allowedTypes.isEmpty() && deniedTypes.isEmpty()) {
165            return allowedSubTypes;
166        }
167
168        Map<String, SubType> filteredAllowedSubTypes = new HashMap<String, SubType>(allowedSubTypes);
169        for (Iterator<String> it = filteredAllowedSubTypes.keySet().iterator(); it.hasNext();) {
170            String subTypeName = it.next();
171            if (deniedTypes.contains(subTypeName) || !allowedTypes.isEmpty() && !allowedTypes.contains(subTypeName)) {
172                it.remove();
173            }
174        }
175        return filteredAllowedSubTypes;
176    }
177
178    /*
179     * (non-Javadoc)
180     * @see org.nuxeo.ecm.platform.types.localconfiguration.UITypesConfiguration# getDefaultType()
181     */
182    @Override
183    public String getDefaultType() {
184        return defaultType;
185    }
186
187}