001/* 002 * Copyright 2002-2018 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.LinkedHashSet; 020import java.util.Set; 021 022import org.springframework.beans.BeanMetadataElement; 023import org.springframework.beans.Mergeable; 024import org.springframework.lang.Nullable; 025 026/** 027 * Tag collection class used to hold managed Set values, which may 028 * include runtime bean references (to be resolved into bean objects). 029 * 030 * @author Juergen Hoeller 031 * @author Rob Harrop 032 * @since 21.01.2004 033 * @param <E> the element type 034 */ 035@SuppressWarnings("serial") 036public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMetadataElement { 037 038 @Nullable 039 private Object source; 040 041 @Nullable 042 private String elementTypeName; 043 044 private boolean mergeEnabled; 045 046 047 public ManagedSet() { 048 } 049 050 public ManagedSet(int initialCapacity) { 051 super(initialCapacity); 052 } 053 054 055 /** 056 * Set the configuration source {@code Object} for this metadata element. 057 * <p>The exact type of the object will depend on the configuration mechanism used. 058 */ 059 public void setSource(@Nullable Object source) { 060 this.source = source; 061 } 062 063 @Override 064 @Nullable 065 public Object getSource() { 066 return this.source; 067 } 068 069 /** 070 * Set the default element type name (class name) to be used for this set. 071 */ 072 public void setElementTypeName(@Nullable String elementTypeName) { 073 this.elementTypeName = elementTypeName; 074 } 075 076 /** 077 * Return the default element type name (class name) to be used for this set. 078 */ 079 @Nullable 080 public String getElementTypeName() { 081 return this.elementTypeName; 082 } 083 084 /** 085 * Set whether merging should be enabled for this collection, 086 * in case of a 'parent' collection value being present. 087 */ 088 public void setMergeEnabled(boolean mergeEnabled) { 089 this.mergeEnabled = mergeEnabled; 090 } 091 092 @Override 093 public boolean isMergeEnabled() { 094 return this.mergeEnabled; 095 } 096 097 @Override 098 @SuppressWarnings("unchecked") 099 public Set<E> merge(@Nullable Object parent) { 100 if (!this.mergeEnabled) { 101 throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'"); 102 } 103 if (parent == null) { 104 return this; 105 } 106 if (!(parent instanceof Set)) { 107 throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]"); 108 } 109 Set<E> merged = new ManagedSet<>(); 110 merged.addAll((Set<E>) parent); 111 merged.addAll(this); 112 return merged; 113 } 114 115}