001/*
002 * (C) Copyright 2006-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 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.platform.actions;
020
021import java.util.ArrayList;
022import java.util.Arrays;
023import java.util.HashSet;
024import java.util.List;
025import java.util.Set;
026
027import org.nuxeo.runtime.model.ContributionFragmentRegistry;
028
029/**
030 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
031 */
032public class ActionContributionHandler extends ContributionFragmentRegistry<Action> {
033
034    protected ActionRegistry actionReg;
035
036    protected FilterContributionHandler filters;
037
038    public ActionContributionHandler(FilterContributionHandler filters) {
039        actionReg = new ActionRegistry();
040        this.filters = filters;
041    }
042
043    public ActionRegistry getRegistry() {
044        return actionReg;
045    }
046
047    @Override
048    public Action clone(Action object) {
049        return object.clone();
050    }
051
052    @Override
053    public void contributionRemoved(String id, Action action) {
054        actionReg.removeAction(id);
055        // also remove local filters
056        ActionFilter[] localFilters = action.getFilters();
057        if (localFilters != null) {
058            for (ActionFilter filter : localFilters) {
059                // XXX: local filters implicitly append their rules to existing
060                // ones => see append to true
061                DefaultActionFilter f = (DefaultActionFilter) filter;
062                f.setAppend(true);
063                filters.removeContribution(f, true);
064            }
065        }
066    }
067
068    @Override
069    public void contributionUpdated(String actionId, Action action, Action origAction) {
070        // given action is already merged, just retrieve its inner filters to
071        // register them to the filter registry
072        List<String> newFilterIds = new ArrayList<String>();
073        List<String> existingFilterIds = action.getFilterIds();
074        if (existingFilterIds != null) {
075            newFilterIds.addAll(existingFilterIds);
076        }
077        ActionFilter[] newFilters = action.getFilters();
078        if (newFilters != null) {
079            // register embedded filters and save corresponding filter ids
080            for (ActionFilter filter : newFilters) {
081                String filterId = filter.getId();
082                // XXX: local filters implicitly append their rules to existing
083                // ones => see append to true
084                DefaultActionFilter f = (DefaultActionFilter) filter;
085                f.setAppend(true);
086                filters.addContribution(f);
087                if (!newFilterIds.contains(filterId)) {
088                    newFilterIds.add(filterId);
089                }
090            }
091            // XXX: Remove filters from action as it was just temporary,
092            // filters are now in their own registry.
093            action.setFilters(null);
094        }
095        action.setFilterIds(newFilterIds);
096
097        actionReg.addAction(action);
098    }
099
100    @Override
101    public String getContributionId(Action contrib) {
102        return contrib.getId();
103    }
104
105    @Override
106    public void merge(Action source, Action dest) {
107        // Icon
108        String newIcon = source.getIcon();
109        if (newIcon != null && !newIcon.equals(dest.getIcon())) {
110            dest.setIcon(newIcon);
111        }
112
113        // Enabled ?
114        if (source.isEnableSet() && source.isEnabled() != dest.isEnabled()) {
115            dest.setEnabled(source.isEnabled());
116        }
117
118        // Merge categories without duplicates
119        Set<String> mergedCategories = new HashSet<String>(Arrays.asList(dest.getCategories()));
120        mergedCategories.addAll(new HashSet<String>(Arrays.asList(source.getCategories())));
121        dest.setCategories(mergedCategories.toArray(new String[mergedCategories.size()]));
122
123        // label
124        String newLabel = source.getLabel();
125        if (newLabel != null && !newLabel.equals(dest.getLabel())) {
126            dest.setLabel(newLabel);
127        }
128
129        // link
130        String newLink = source.getLink();
131        if (newLink != null && !newLink.equals(dest.getLink())) {
132            dest.setLink(newLink);
133        }
134
135        // confirm
136        String newConfirm = source.getConfirm();
137        if (newConfirm != null && !"".equals(newConfirm) && !newConfirm.equals(dest.getConfirm())) {
138            dest.setConfirm(newConfirm);
139        }
140
141        // title (tooltip)
142        String tooltip = source.getHelp();
143        if (tooltip != null && !tooltip.equals(dest.getHelp())) {
144            dest.setHelp(tooltip);
145        }
146
147        // ui action type
148        String type = source.getType();
149        if (type != null && !type.equals(dest.getType())) {
150            dest.setType(type);
151        }
152
153        // order
154        int newOrder = source.getOrder();
155        if (newOrder > 0 && newOrder != dest.getOrder()) {
156            dest.setOrder(newOrder);
157        }
158
159        // filter ids
160        List<String> newFilterIds = new ArrayList<String>();
161        newFilterIds.addAll(dest.getFilterIds());
162        newFilterIds.addAll(source.getFilterIds());
163        dest.setFilterIds(newFilterIds);
164
165        // filters
166        ActionFilter[] existingFilters = dest.getFilters();
167        ActionFilter[] newFilters = source.getFilters();
168        List<ActionFilter> filters = new ArrayList<ActionFilter>();
169        if (existingFilters != null) {
170            filters.addAll(Arrays.asList(existingFilters));
171        }
172        if (newFilters != null) {
173            filters.addAll(Arrays.asList(newFilters));
174        }
175        dest.setFilters(filters.toArray(new ActionFilter[] {}));
176
177        // accessKey
178        String newAccessKey = source.getAccessKey();
179        if (newAccessKey != null && !newAccessKey.isEmpty()) {
180            dest.setAccessKey(newAccessKey);
181        }
182
183        // properties
184        ActionPropertiesDescriptor newProps = source.getPropertiesDescriptor();
185        if (newProps != null) {
186            boolean append = newProps.isAppend();
187            if (!append) {
188                dest.setPropertiesDescriptor(newProps);
189            } else {
190                ActionPropertiesDescriptor oldProps = dest.getPropertiesDescriptor();
191                if (oldProps != null) {
192                    oldProps.merge(newProps);
193                    dest.setPropertiesDescriptor(oldProps);
194                } else {
195                    dest.setPropertiesDescriptor(newProps);
196                }
197            }
198        }
199
200    }
201}