001/*
002 * (C) Copyright 2006-2008 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 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.webengine.model.impl;
021
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.List;
025import java.util.Map;
026import java.util.concurrent.ConcurrentHashMap;
027
028import org.nuxeo.ecm.webengine.model.LinkDescriptor;
029import org.nuxeo.ecm.webengine.model.Resource;
030import org.nuxeo.runtime.contribution.impl.AbstractContributionRegistry;
031
032/**
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035public class LinkRegistry extends AbstractContributionRegistry<String, LinkDescriptor> {
036
037    // type to view bindings
038    protected final Map<String, LinkDescriptor[]> links; // category to links mapping
039
040    public LinkRegistry() {
041        links = new ConcurrentHashMap<String, LinkDescriptor[]>();
042    }
043
044    public List<LinkDescriptor> getLinks(String category) {
045        LinkDescriptor[] descriptors = links.get(category);
046        if (descriptors != null && descriptors.length > 0) {
047            return Arrays.asList(descriptors);
048        }
049        return new ArrayList<LinkDescriptor>();
050    }
051
052    public List<LinkDescriptor> getActiveLinks(Resource context, String category) {
053        List<LinkDescriptor> result = new ArrayList<LinkDescriptor>();
054        LinkDescriptor[] descriptors = links.get(category);
055        if (descriptors != null && descriptors.length > 0) {
056            for (LinkDescriptor descriptor : descriptors) {
057                if (descriptor.isEnabled(context)) {
058                    result.add(descriptor);
059                }
060            }
061        }
062        return result;
063    }
064
065    public synchronized void registerLink(LinkDescriptor td) {
066        addFragment(td.getId(), td);
067    }
068
069    public void unregisterLink(LinkDescriptor td) {
070        removeFragment(td.getId(), td);
071    }
072
073    @Override
074    protected LinkDescriptor clone(LinkDescriptor object) {
075        try {
076            return object.clone();
077        } catch (CloneNotSupportedException e) {
078            throw new RuntimeException("Must never happens");
079        }
080    }
081
082    @Override
083    protected void applyFragment(LinkDescriptor object, LinkDescriptor fragment) {
084        // a view fragment may be used to replace the view implementation class and optionally the guard
085        // and/or to add new categories
086        object.applyFragment(fragment);
087    }
088
089    @Override
090    protected void applySuperFragment(LinkDescriptor object, LinkDescriptor superFragment) {
091        // links are not using inheritance
092    }
093
094    @Override
095    protected void installContribution(String key, LinkDescriptor object) {
096        List<String> cats = object.getCategories();
097        for (String cat : cats) {
098            installLink(cat, object);
099        }
100    }
101
102    @Override
103    protected void updateContribution(String key, LinkDescriptor object, LinkDescriptor oldValue) {
104        removeLink(oldValue);
105        installContribution(key, object);
106    }
107
108    @Override
109    protected void uninstallContribution(String key, LinkDescriptor object) {
110        removeLink(object);
111    }
112
113    @Override
114    protected boolean isMainFragment(LinkDescriptor object) {
115        return !object.isFragment();
116    }
117
118    protected void installLink(String category, LinkDescriptor link) {
119        LinkDescriptor[] descriptors = links.get(category);
120        if (descriptors == null) {
121            descriptors = new LinkDescriptor[] { link };
122        } else {
123            LinkDescriptor[] ar = new LinkDescriptor[descriptors.length + 1];
124            System.arraycopy(descriptors, 0, ar, 0, descriptors.length);
125            ar[descriptors.length] = link;
126            descriptors = ar;
127        }
128        links.put(category, descriptors);
129    }
130
131    protected void removeLink(LinkDescriptor link) {
132        List<String> cats = link.getCategories();
133        for (String cat : cats) {
134            removeLink(cat, link);
135        }
136    }
137
138    protected void removeLink(String category, LinkDescriptor link) {
139        LinkDescriptor[] descriptors = links.get(category);
140        if (descriptors == null) {
141            return;
142        }
143        for (int i = 0; i < descriptors.length; i++) {
144            // FIXME: this can't work, comparison between a String and a LinkDescriptor
145            if (link.getId().equals(descriptors[i])) {
146                if (descriptors.length == 1 && i == 0) {
147                    links.remove(category);
148                    return;
149                } else {
150                    LinkDescriptor[] tmp = new LinkDescriptor[descriptors.length - 1];
151                    if (i > 0) {
152                        System.arraycopy(descriptors, 0, tmp, 0, i);
153                    }
154                    if (i < descriptors.length - 1) {
155                        System.arraycopy(descriptors, i + 1, tmp, i, descriptors.length - i - 1);
156                    }
157                    links.put(category, tmp);
158                    return;
159                }
160            }
161        }
162    }
163
164}