001/*
002 * (C) Copyright 2006-2007 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 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 */
019
020package org.nuxeo.runtime.deployment.preprocessor;
021
022import java.util.ArrayList;
023import java.util.Collection;
024import java.util.HashMap;
025import java.util.List;
026import java.util.Map;
027
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030import org.nuxeo.common.collections.DependencyTree;
031
032/**
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035public class FragmentRegistry extends DependencyTree<String, FragmentDescriptor> {
036
037    private static final Log log = LogFactory.getLog(FragmentRegistry.class);
038
039    // this is needed to handle requiredBy dependencies
040    protected final Map<String, FragmentDescriptor> fragments = new HashMap<String, FragmentDescriptor>();
041
042    public void add(FragmentDescriptor fragment) {
043        if (fragments.containsKey(fragment.name)) {
044            FragmentDescriptor existing = fragments.get(fragment.name);
045            log.error(String.format("Overriding fragment with name '%s' and path '%s' "
046                    + "that is already present with path '%s'", fragment.name, fragment.filePath, existing.filePath));
047        }
048        fragments.put(fragment.name, fragment);
049    }
050
051    @Override
052    public List<Entry<String, FragmentDescriptor>> getResolvedEntries() {
053        if (!fragments.isEmpty()) {
054            commitFragments();
055        }
056        return super.getResolvedEntries();
057    }
058
059    @Override
060    public List<Entry<String, FragmentDescriptor>> getMissingRequirements() {
061        if (!fragments.isEmpty()) {
062            commitFragments();
063        }
064        return super.getMissingRequirements();
065    }
066
067    @Override
068    public FragmentDescriptor get(String key) {
069        if (!fragments.isEmpty()) {
070            commitFragments();
071        }
072        return super.get(key);
073    }
074
075    @Override
076    public Collection<Entry<String, FragmentDescriptor>> getEntries() {
077        if (!fragments.isEmpty()) {
078            commitFragments();
079        }
080        return super.getEntries();
081    }
082
083    @Override
084    public List<FragmentDescriptor> getResolvedObjects() {
085        if (!fragments.isEmpty()) {
086            commitFragments();
087        }
088        return super.getResolvedObjects();
089    }
090
091    @Override
092    public List<FragmentDescriptor> getPendingObjects() {
093        if (!fragments.isEmpty()) {
094            commitFragments();
095        }
096        return super.getPendingObjects();
097    }
098
099    @Override
100    public Entry<String, FragmentDescriptor> getEntry(String key) {
101        if (!fragments.isEmpty()) {
102            commitFragments();
103        }
104        return super.getEntry(key);
105    }
106
107    @Override
108    public List<Entry<String, FragmentDescriptor>> getPendingEntries() {
109        if (!fragments.isEmpty()) {
110            commitFragments();
111        }
112        return super.getPendingEntries();
113    }
114
115    protected void commitFragments() {
116
117        // update requires depending on requiredBy
118        for (FragmentDescriptor fd : fragments.values()) {
119            if (fd.requiredBy != null && fd.requiredBy.length > 0) {
120                for (String reqBy : fd.requiredBy) {
121                    FragmentDescriptor fdRegBy = fragments.get(reqBy);
122                    if (fdRegBy != null) {
123                        if (fdRegBy.requires == null) {
124                            fdRegBy.requires = new ArrayList<String>();
125                        }
126                        fdRegBy.requires.add(fd.name);
127                    }
128                }
129            }
130        }
131
132        // add fragments to the dependency tree
133        for (FragmentDescriptor fd : fragments.values()) {
134            add(fd.name, fd, fd.requires);
135        }
136
137        // add the "all" marker fragment
138        add(FragmentDescriptor.ALL.name, FragmentDescriptor.ALL, (Collection<String>) null);
139
140        fragments.clear();
141    }
142
143}