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