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