001/* 002 * Copyright 2002-2017 the original author or authors. 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 * https://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 017package org.springframework.beans.factory.support; 018 019import java.util.Properties; 020 021import org.springframework.beans.BeanMetadataElement; 022import org.springframework.beans.Mergeable; 023import org.springframework.lang.Nullable; 024 025/** 026 * Tag class which represents a Spring-managed {@link Properties} instance 027 * that supports merging of parent/child definitions. 028 * 029 * @author Rob Harrop 030 * @author Juergen Hoeller 031 * @since 2.0 032 */ 033@SuppressWarnings("serial") 034public class ManagedProperties extends Properties implements Mergeable, BeanMetadataElement { 035 036 @Nullable 037 private Object source; 038 039 private boolean mergeEnabled; 040 041 042 /** 043 * Set the configuration source {@code Object} for this metadata element. 044 * <p>The exact type of the object will depend on the configuration mechanism used. 045 */ 046 public void setSource(@Nullable Object source) { 047 this.source = source; 048 } 049 050 @Override 051 @Nullable 052 public Object getSource() { 053 return this.source; 054 } 055 056 /** 057 * Set whether merging should be enabled for this collection, 058 * in case of a 'parent' collection value being present. 059 */ 060 public void setMergeEnabled(boolean mergeEnabled) { 061 this.mergeEnabled = mergeEnabled; 062 } 063 064 @Override 065 public boolean isMergeEnabled() { 066 return this.mergeEnabled; 067 } 068 069 070 @Override 071 public Object merge(@Nullable Object parent) { 072 if (!this.mergeEnabled) { 073 throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'"); 074 } 075 if (parent == null) { 076 return this; 077 } 078 if (!(parent instanceof Properties)) { 079 throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]"); 080 } 081 Properties merged = new ManagedProperties(); 082 merged.putAll((Properties) parent); 083 merged.putAll(this); 084 return merged; 085 } 086 087}