001/*
002 * (C) Copyright 2006-2007 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 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
020 */
021
022package org.nuxeo.ecm.platform.types;
023
024import java.util.ArrayList;
025import java.util.Collection;
026import java.util.Collections;
027import java.util.HashMap;
028import java.util.List;
029import java.util.Map;
030import java.util.Set;
031
032import org.nuxeo.runtime.model.ContributionFragmentRegistry;
033
034public class TypeRegistry extends ContributionFragmentRegistry<Type> {
035
036    protected Map<String, Type> types = new HashMap<String, Type>();
037
038    @Override
039    public String getContributionId(Type contrib) {
040        return contrib.getId();
041    }
042
043    @Override
044    public void contributionUpdated(String id, Type contrib, Type newOrigContrib) {
045        if (contrib.getRemove()) {
046            types.remove(id);
047        } else {
048            types.put(id, contrib);
049        }
050    }
051
052    @Override
053    public void contributionRemoved(String id, Type origContrib) {
054        types.remove(id);
055    }
056
057    @Override
058    public Type clone(Type orig) {
059        if (orig != null) {
060            return orig.clone();
061        }
062        return null;
063    }
064
065    @Override
066    public void merge(Type newType, Type oldType) {
067        boolean remove = newType.getRemove();
068        // keep old remove info: if old type was removed, new type should
069        // replace the old one completely
070        boolean wasRemoved = oldType.getRemove();
071        oldType.setRemove(remove);
072        if (remove) {
073            // don't bother merging
074            return;
075        }
076
077        String icon = newType.getIcon();
078        if (icon != null || wasRemoved) {
079            oldType.setIcon(icon);
080        }
081        String iconExpanded = newType.getIconExpanded();
082        if (iconExpanded != null || wasRemoved) {
083            oldType.setIconExpanded(iconExpanded);
084        }
085        String bigIcon = newType.getBigIcon();
086        if (bigIcon != null || wasRemoved) {
087            oldType.setBigIcon(bigIcon);
088        }
089        String bigIconExpanded = newType.getBigIconExpanded();
090        if (bigIconExpanded != null || wasRemoved) {
091            oldType.setBigIconExpanded(bigIconExpanded);
092        }
093        String label = newType.getLabel();
094        if (label != null || wasRemoved) {
095            oldType.setLabel(label);
096        }
097        String description = newType.getDescription();
098        if (description != null || wasRemoved) {
099            oldType.setDescription(description);
100        }
101        String category = newType.getCategory();
102        if (category != null || wasRemoved) {
103            oldType.setCategory(category);
104        }
105
106        Map<String, SubType> newTypeAllowedSubTypes = newType.getAllowedSubTypes();
107        if (wasRemoved) {
108            oldType.setAllowedSubTypes(newTypeAllowedSubTypes);
109        } else {
110            if (newTypeAllowedSubTypes != null) {
111                Set<String> newTypeKeySet = newTypeAllowedSubTypes.keySet();
112                Map<String, SubType> oldTypeAllowedSubTypes = oldType.getAllowedSubTypes();
113                for (String newTypeKey : newTypeKeySet) {
114                    oldTypeAllowedSubTypes.put(newTypeKey, newTypeAllowedSubTypes.get(newTypeKey));
115                }
116
117            }
118
119            // Code added to delete the denied SubType from allowed subtypes
120
121            List<String> result = new ArrayList<String>();
122            String[] deniedSubTypes = newType.getDeniedSubTypes();
123            Map<String, SubType> oldTypeAllowedSubTypes = oldType.getAllowedSubTypes();
124            boolean toAdd = true;
125
126            if (oldTypeAllowedSubTypes != null) {
127                Set<String> oldTypeKeySet = oldTypeAllowedSubTypes.keySet();
128                for (String allowedSubType : oldTypeKeySet) {
129                    for (String deniedSubType : deniedSubTypes) {
130                        if (deniedSubType.equals(allowedSubType)) {
131                            toAdd = false;
132                            break;
133                        }
134                    }
135                    if (toAdd) {
136                        result.add(allowedSubType);
137                    }
138                    toAdd = true;
139                }
140            }
141
142            Map<String, SubType> mapResult = new HashMap<String, SubType>();
143            for (String resultTypeName : result) {
144                mapResult.put(resultTypeName, oldTypeAllowedSubTypes.get(resultTypeName));
145            }
146
147            oldType.setAllowedSubTypes(mapResult);
148
149            // end of added code
150        }
151
152        String defaultView = newType.getDefaultView();
153        if (defaultView != null || wasRemoved) {
154            oldType.setDefaultView(defaultView);
155        }
156        String createView = newType.getCreateView();
157        if (createView != null || wasRemoved) {
158            oldType.setCreateView(createView);
159        }
160        String editView = newType.getEditView();
161        if (editView != null || wasRemoved) {
162            oldType.setEditView(editView);
163        }
164
165        for (TypeView view : newType.getViews()) {
166            oldType.setView(view);
167        }
168
169        Map<String, Layouts> layouts = newType.getLayouts();
170        if (wasRemoved) {
171            oldType.setLayouts(layouts);
172        } else {
173            if (layouts != null) {
174                Map<String, Layouts> layoutsMerged = new HashMap<String, Layouts>(oldType.getLayouts());
175                for (Map.Entry<String, Layouts> entry : layouts.entrySet()) {
176                    String key = entry.getKey();
177                    Layouts newLayouts = entry.getValue();
178                    if (layoutsMerged.containsKey(key) && newLayouts.getAppend()) {
179                        List<String> allLayouts = new ArrayList<String>();
180                        for (String layoutName : layoutsMerged.get(key).getLayouts()) {
181                            allLayouts.add(layoutName);
182                        }
183                        for (String layoutName : newLayouts.getLayouts()) {
184                            allLayouts.add(layoutName);
185                        }
186                        Layouts mergedLayouts = new Layouts();
187                        mergedLayouts.layouts = allLayouts.toArray(new String[allLayouts.size()]);
188                        layoutsMerged.put(key, mergedLayouts);
189                    } else {
190                        layoutsMerged.put(key, newLayouts);
191                    }
192                }
193                oldType.setLayouts(layoutsMerged);
194            }
195        }
196
197        Map<String, DocumentContentViews> contentViews = newType.getContentViews();
198        if (wasRemoved) {
199            oldType.setContentViews(contentViews);
200        } else {
201            if (contentViews != null) {
202                Map<String, DocumentContentViews> cvMerged = new HashMap<String, DocumentContentViews>(
203                        oldType.getContentViews());
204                for (Map.Entry<String, DocumentContentViews> entry : contentViews.entrySet()) {
205                    String key = entry.getKey();
206                    DocumentContentViews newContentViews = entry.getValue();
207                    if (cvMerged.containsKey(key) && newContentViews.getAppend()) {
208                        List<DocumentContentView> allContentViews = new ArrayList<DocumentContentView>();
209                        for (DocumentContentView cv : cvMerged.get(key).getContentViews()) {
210                            allContentViews.add(cv);
211                        }
212                        for (DocumentContentView cv : newContentViews.getContentViews()) {
213                            allContentViews.add(cv);
214                        }
215                        DocumentContentViews mergedContentViews = new DocumentContentViews();
216                        mergedContentViews.contentViews = allContentViews.toArray(new DocumentContentView[allContentViews.size()]);
217                        cvMerged.put(key, mergedContentViews);
218                    } else {
219                        cvMerged.put(key, newContentViews);
220                    }
221                }
222                oldType.setContentViews(cvMerged);
223            }
224        }
225    }
226
227    public boolean hasType(String id) {
228        return types.containsKey(id);
229    }
230
231    public Collection<Type> getTypes() {
232        return Collections.unmodifiableCollection(types.values());
233    }
234
235    public Type getType(String id) {
236        return types.get(id);
237    }
238
239}