001/*
002 * (C) Copyright 2006-2007 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 *     Jean-Marc Orliaguet, Chalmers
018 *
019 * $Id$
020 */
021
022package org.nuxeo.theme.types;
023
024import java.util.ArrayList;
025import java.util.List;
026import java.util.Map;
027import java.util.concurrent.ConcurrentHashMap;
028
029import org.apache.commons.logging.Log;
030import org.apache.commons.logging.LogFactory;
031import org.nuxeo.theme.Registrable;
032
033public final class TypeRegistry implements Registrable {
034
035    private static final Log log = LogFactory.getLog(TypeRegistry.class);
036
037    private final Map<String, Type> registry = new ConcurrentHashMap<String, Type>();
038
039    private final Map<TypeFamily, List<String>> typeNames = new ConcurrentHashMap<TypeFamily, List<String>>();
040
041    public synchronized void register(final Type type) {
042        String typeName = type.getTypeName();
043        TypeFamily typeFamily = type.getTypeFamily();
044        String key = computeKey(typeFamily, typeName);
045        if (registry.containsKey(key)) {
046            log.debug("Overriding theme " + typeFamily + ": " + typeName);
047        }
048        registry.put(key, type);
049        if (!typeNames.containsKey(typeFamily)) {
050            typeNames.put(typeFamily, new ArrayList<String>());
051        }
052        List<String> typeNamesByFamily = typeNames.get(typeFamily);
053        if (!typeNamesByFamily.contains(typeName)) {
054            typeNamesByFamily.add(typeName);
055        }
056        log.debug("Registered theme " + typeFamily + ": " + typeName);
057    }
058
059    public synchronized void unregister(final Type type) {
060        String typeName = type.getTypeName();
061        TypeFamily typeFamily = type.getTypeFamily();
062        String key = computeKey(typeFamily, typeName);
063        registry.remove(key);
064        if (typeNames.containsKey(typeFamily)) {
065            typeNames.get(typeFamily).remove(typeName);
066        }
067        log.debug("Unregistered theme " + typeFamily + ": " + typeName);
068    }
069
070    public Type lookup(final TypeFamily typeFamily, final String name) {
071        String key = computeKey(typeFamily, name);
072        return registry.get(key);
073    }
074
075    public Type lookup(final TypeFamily typeFamily, final String... names) {
076        for (String name : names) {
077            if (name == null) {
078                continue;
079            }
080            String key = computeKey(typeFamily, name);
081            Type type = registry.get(key);
082            if (type != null) {
083                return type;
084            }
085        }
086        return null;
087
088    }
089
090    public List<String> getTypeNames(final TypeFamily typeFamily) {
091        if (!typeNames.containsKey(typeFamily)) {
092            return new ArrayList<String>();
093        }
094        return typeNames.get(typeFamily);
095    }
096
097    public List<Type> getTypes(final TypeFamily typeFamily) {
098        List<Type> types = new ArrayList<Type>();
099        if (typeNames.containsKey(typeFamily)) {
100            for (String typeName : typeNames.get(typeFamily)) {
101                types.add(lookup(typeFamily, typeName));
102            }
103        }
104        return types;
105    }
106
107    private static String computeKey(final TypeFamily family, final String name) {
108        return String.format("%s/%s", family, name);
109    }
110
111    @Override
112    public synchronized void clear() {
113        registry.clear();
114        typeNames.clear();
115    }
116
117}