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