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 org.apache.commons.logging.Log; 018import org.apache.commons.logging.LogFactory; 019 020/** 021 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 022 */ 023public abstract class ExtensibleContribution extends Contribution { 024 025 private static final Log log = LogFactory.getLog(ExtensibleContribution.class); 026 027 protected ExtensibleContribution baseContribution; 028 029 protected String baseContributionId; 030 031 /** 032 * Copy this contribution data over the given one. 033 * <p> 034 * Warn that the copy must be done deeply - you should clone every element in any collection you have. This is to 035 * avoid merging data you copy into the base contribution and breaking subsequent merging operations. 036 * <p> 037 * The baseContributionId and contributionId fields should not be copied since their are copied by the base classes 038 * implementation. 039 */ 040 protected abstract void copyOver(ExtensibleContribution contrib); 041 042 public String getBaseContributionId() { 043 return baseContributionId; 044 } 045 046 public void setBaseContribution(ExtensibleContribution baseContribution) { 047 this.baseContribution = baseContribution; 048 } 049 050 public void setBaseContributionId(String baseContributionId) { 051 this.baseContributionId = baseContributionId; 052 } 053 054 @Override 055 public void resolve(ContributionManager mgr) { 056 if (baseContributionId != null) { 057 baseContribution = (ExtensibleContribution) mgr.getResolved(baseContributionId); 058 } 059 } 060 061 @Override 062 public void unresolve(ContributionManager mgr) { 063 baseContribution = null; 064 } 065 066 public ExtensibleContribution getBaseContribution() { 067 return baseContribution; 068 } 069 070 public ExtensibleContribution getRootContribution() { 071 return baseContribution == null ? this : baseContribution.getRootContribution(); 072 } 073 074 public boolean isRootContribution() { 075 return baseContribution == null; 076 } 077 078 protected ExtensibleContribution getMergedContribution() { 079 if (baseContribution == null) { 080 return clone(); 081 } 082 ExtensibleContribution mc = baseContribution.getMergedContribution(); 083 copyOver(mc); 084 mc.contributionId = contributionId; 085 mc.baseContributionId = baseContributionId; 086 return mc; 087 } 088 089 @Override 090 public void install(ManagedComponent comp) { 091 install(comp, getMergedContribution()); 092 } 093 094 @Override 095 public void uninstall(ManagedComponent comp) { 096 uninstall(comp, getMergedContribution()); 097 } 098 099 /** 100 * perform a deep clone to void sharing collection elements between clones 101 */ 102 @Override 103 public ExtensibleContribution clone() { 104 ExtensibleContribution clone; 105 try { 106 clone = getClass().newInstance(); 107 } catch (ReflectiveOperationException e) { 108 throw new RuntimeException("Failed to instantiate the contribution class. " 109 + "Contribution classes must have a trivial constructor", e); 110 } 111 copyOver(clone); 112 clone.contributionId = contributionId; 113 clone.baseContributionId = baseContributionId; 114 return clone; 115 } 116 117}