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 *
019 * $Id$
020 */
021
022package org.nuxeo.runtime.deploy;
023
024import java.util.ArrayList;
025import java.util.List;
026
027/**
028 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
029 */
030public abstract class CompositeContribution extends ExtensibleContribution {
031
032    protected final List<CompositeContribution> contributionFragments = new ArrayList<CompositeContribution>();
033
034    private boolean isContributionEnabled;
035
036    @Override
037    public void resolve(ContributionManager mgr) {
038        super.resolve(mgr);
039        if (baseContribution instanceof CompositeContribution) {
040            ((CompositeContribution) baseContribution).addContributionFragment(this);
041        }
042    }
043
044    @Override
045    public void unresolve(ContributionManager mgr) {
046        if (baseContribution instanceof CompositeContribution) {
047            ((CompositeContribution) baseContribution).removeContributionFragment(this);
048        }
049        super.unresolve(mgr);
050    }
051
052    public boolean isContributionEnabled() {
053        return isContributionEnabled;
054    }
055
056    private void setContributionEnabled(boolean isEnabled) {
057        isContributionEnabled = isEnabled;
058    }
059
060    private void addContributionFragment(CompositeContribution fragment) {
061        fragment.setContributionEnabled(true);
062        int index = contributionFragments.indexOf(fragment);
063        if (index > -1) {
064            contributionFragments.set(index, fragment);
065        } else {
066            contributionFragments.add(fragment);
067        }
068    }
069
070    private void removeContributionFragment(CompositeContribution fragment) {
071        int index = contributionFragments.indexOf(fragment);
072        if (index > -1) { // do not physically remove fragments since they can be reloaded
073            contributionFragments.get(index).setContributionEnabled(false);
074        }
075    }
076
077    public List<CompositeContribution> getContributionFragments() {
078        return contributionFragments;
079    }
080
081    private CompositeContribution getRootComposite() {
082        if (baseContribution instanceof CompositeContribution) {
083            return ((CompositeContribution) baseContribution).getRootComposite();
084        }
085        return this;
086    }
087
088    @Override
089    protected ExtensibleContribution getMergedContribution() {
090        CompositeContribution root = getRootComposite();
091        ExtensibleContribution mc = root.baseContribution != null ? root.baseContribution.getMergedContribution()
092                : root.clone();
093        for (CompositeContribution fragment : root.contributionFragments) {
094            if (fragment.isContributionEnabled()) {
095                copyFragmentsOver(mc);
096            }
097        }
098        mc.contributionId = root.contributionId;
099        mc.baseContributionId = root.baseContributionId;
100        return mc;
101    }
102
103    private void copyFragmentsOver(ExtensibleContribution mc) {
104        copyOver(mc);
105        for (CompositeContribution fragment : contributionFragments) {
106            if (fragment.isContributionEnabled()) {
107                fragment.copyFragmentsOver(mc);
108            }
109        }
110    }
111
112    @Override
113    public String toString() {
114        if (baseContributionId == null) {
115            return contributionId;
116        }
117        return contributionId + "@" + baseContributionId;
118    }
119
120}