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