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