001/*
002 * (C) Copyright 2006-2011 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.runtime.services.resource;
020
021import java.net.URL;
022import java.util.ArrayList;
023import java.util.List;
024import java.util.Map;
025import java.util.concurrent.ConcurrentHashMap;
026
027import org.nuxeo.runtime.model.ComponentContext;
028import org.nuxeo.runtime.model.ComponentInstance;
029import org.nuxeo.runtime.model.DefaultComponent;
030import org.nuxeo.runtime.model.Extension;
031
032/**
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035// FIXME: make it handle hot reload correctly
036public class ResourceService extends DefaultComponent {
037
038    public final static String XP_RESOURCES = "resources";
039
040    protected Map<String, URL> registry;
041
042    protected List<Extension> extensions = new ArrayList<>();
043
044    public ResourceService() {
045    }
046
047    @Override
048    public void registerExtension(Extension extension) {
049        super.registerExtension(extension);
050        extensions.add(extension);
051    }
052
053    @Override
054    public void unregisterExtension(Extension extension) {
055        extensions.remove(extension);
056        super.unregisterExtension(extension);
057    }
058
059    public void reload(ComponentContext context) {
060        deactivate(context);
061        activate(context);
062        for (Extension xt : extensions) {
063            super.registerExtension(xt);
064        }
065    }
066
067    public List<Extension> getExtensions() {
068        return extensions;
069    }
070
071    public URL getResource(String name) {
072        return registry.get(name);
073    }
074
075    public void addResource(ResourceDescriptor resource) {
076        addResource(resource.getName(), resource.getResource().toURL());
077    }
078
079    public void addResource(String name, URL url) {
080        registry.put(name, url);
081    }
082
083    public URL removeResource(String name) {
084        return registry.remove(name);
085    }
086
087    @Override
088    public void activate(ComponentContext context) {
089        registry = new ConcurrentHashMap<String, URL>();
090    }
091
092    @Override
093    public void deactivate(ComponentContext context) {
094        registry = null;
095    }
096
097    @Override
098    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
099        if (XP_RESOURCES.equals(extensionPoint)) {
100            addResource((ResourceDescriptor) contribution);
101        }
102    }
103
104    @Override
105    public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
106        if (XP_RESOURCES.equals(extensionPoint)) {
107            ResourceDescriptor rd = (ResourceDescriptor) contribution;
108            ResourceDescriptor last = findLastContributedResource(rd.getName());
109            if (last != null) {
110                addResource(last);
111            } else {
112                removeResource(rd.getName());
113            }
114        }
115    }
116
117    protected ResourceDescriptor findLastContributedResource(String name) {
118        for (int i = extensions.size() - 1; i >= 0; i--) {
119            Extension xt = extensions.get(i);
120            Object[] contribs = xt.getContributions();
121            for (int k = contribs.length - 1; k >= 0; k--) {
122                ResourceDescriptor r = (ResourceDescriptor) contribs[k];
123                if (name.equals(r.getName())) {
124                    return r;
125                }
126            }
127        }
128        return null;
129    }
130}