001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 *
012 * $Id$
013 */
014
015package org.nuxeo.runtime.deploy;
016
017import java.util.ArrayList;
018import java.util.List;
019
020/**
021 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
022 */
023public abstract class CompositeContribution extends ExtensibleContribution {
024
025    protected final List<CompositeContribution> contributionFragments = new ArrayList<CompositeContribution>();
026
027    private boolean isContributionEnabled;
028
029    @Override
030    public void resolve(ContributionManager mgr) {
031        super.resolve(mgr);
032        if (baseContribution instanceof CompositeContribution) {
033            ((CompositeContribution) baseContribution).addContributionFragment(this);
034        }
035    }
036
037    @Override
038    public void unresolve(ContributionManager mgr) {
039        if (baseContribution instanceof CompositeContribution) {
040            ((CompositeContribution) baseContribution).removeContributionFragment(this);
041        }
042        super.unresolve(mgr);
043    }
044
045    public boolean isContributionEnabled() {
046        return isContributionEnabled;
047    }
048
049    private void setContributionEnabled(boolean isEnabled) {
050        isContributionEnabled = isEnabled;
051    }
052
053    private void addContributionFragment(CompositeContribution fragment) {
054        fragment.setContributionEnabled(true);
055        int index = contributionFragments.indexOf(fragment);
056        if (index > -1) {
057            contributionFragments.set(index, fragment);
058        } else {
059            contributionFragments.add(fragment);
060        }
061    }
062
063    private void removeContributionFragment(CompositeContribution fragment) {
064        int index = contributionFragments.indexOf(fragment);
065        if (index > -1) { // do not physically remove fragments since they can be reloaded
066            contributionFragments.get(index).setContributionEnabled(false);
067        }
068    }
069
070    public List<CompositeContribution> getContributionFragments() {
071        return contributionFragments;
072    }
073
074    private CompositeContribution getRootComposite() {
075        if (baseContribution instanceof CompositeContribution) {
076            return ((CompositeContribution) baseContribution).getRootComposite();
077        }
078        return this;
079    }
080
081    @Override
082    protected ExtensibleContribution getMergedContribution() {
083        CompositeContribution root = getRootComposite();
084        ExtensibleContribution mc = root.baseContribution != null ? root.baseContribution.getMergedContribution()
085                : root.clone();
086        for (CompositeContribution fragment : root.contributionFragments) {
087            if (fragment.isContributionEnabled()) {
088                copyFragmentsOver(mc);
089            }
090        }
091        mc.contributionId = root.contributionId;
092        mc.baseContributionId = root.baseContributionId;
093        return mc;
094    }
095
096    private void copyFragmentsOver(ExtensibleContribution mc) {
097        copyOver(mc);
098        for (CompositeContribution fragment : contributionFragments) {
099            if (fragment.isContributionEnabled()) {
100                fragment.copyFragmentsOver(mc);
101            }
102        }
103    }
104
105    @Override
106    public String toString() {
107        if (baseContributionId == null) {
108            return contributionId;
109        }
110        return contributionId + "@" + baseContributionId;
111    }
112
113}