001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.xbean.recipe;
018
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.Iterator;
022 import java.util.LinkedHashSet;
023 import java.util.List;
024 import java.util.Set;
025 import java.util.SortedSet;
026 import java.util.TreeSet;
027
028 /**
029 * @version $Rev: 6685 $ $Date: 2005-12-28T00:29:37.967210Z $
030 */
031 public class CollectionRecipe extends AbstractRecipe {
032 private final List<Object> list;
033 private final String type;
034
035 public CollectionRecipe() {
036 list = new ArrayList<Object>();
037 type = ArrayList.class.getName();
038 }
039
040 public CollectionRecipe(String type) {
041 list = new ArrayList<Object>();
042 this.type = type;
043 }
044
045 public CollectionRecipe(Class type) {
046 if (type == null) throw new NullPointerException("type is null");
047 if (!RecipeHelper.hasDefaultConstructor(type)) throw new IllegalArgumentException("Type does not have a default constructor " + type);
048 this.list = new ArrayList<Object>();
049 this.type = type.getName();
050 }
051
052 public CollectionRecipe(Collection collection) {
053 if (collection == null) throw new NullPointerException("collection is null");
054
055 this.list = new ArrayList<Object>(collection.size());
056
057 // If the specified set has a default constructor we will recreate the set, otherwise we use a the default
058 if (RecipeHelper.hasDefaultConstructor(collection.getClass())) {
059 this.type = collection.getClass().getName();
060 } else if (collection instanceof SortedSet) {
061 this.type = TreeSet.class.getName();
062 } else if (collection instanceof Set) {
063 this.type = LinkedHashSet.class.getName();
064 } else {
065 this.type = ArrayList.class.getName();
066 }
067 addAll(collection);
068 }
069
070 public CollectionRecipe(String type, Collection collection) {
071 if (type == null) throw new NullPointerException("type is null");
072 if (collection == null) throw new NullPointerException("collection is null");
073 this.list = new ArrayList<Object>(collection.size());
074 this.type = type;
075 addAll(collection);
076 }
077
078 public CollectionRecipe(Class type, Collection collection) {
079 if (type == null) throw new NullPointerException("type is null");
080 if (!RecipeHelper.hasDefaultConstructor(type)) throw new IllegalArgumentException("Type does not have a default constructor " + type);
081 if (collection == null) throw new NullPointerException("collection is null");
082 this.list = new ArrayList<Object>(collection.size());
083 this.type = type.getName();
084 addAll(collection);
085 }
086
087 public CollectionRecipe(CollectionRecipe collectionRecipe) {
088 if (collectionRecipe == null) throw new NullPointerException("setRecipe is null");
089 this.type = collectionRecipe.type;
090 list = new ArrayList<Object>(collectionRecipe.list);
091 }
092
093 public boolean canCreate(Class type, ClassLoader classLoader) {
094 Class myType = getType(classLoader);
095 return type.isAssignableFrom(myType);
096 }
097
098 public Collection create(ClassLoader classLoader) {
099 Class setType = getType(classLoader);
100
101 if (!RecipeHelper.hasDefaultConstructor(setType)) {
102 throw new ConstructionException("Type does not have a default constructor " + type);
103 }
104
105 Object o;
106 try {
107 o = setType.newInstance();
108 } catch (Exception e) {
109 throw new ConstructionException("Error while creating set instance: " + type);
110 }
111
112 if(!(o instanceof Collection)) {
113 throw new ConstructionException("Specified set type does not implement the Collection interface: " + type);
114 }
115
116 Collection instance = (Collection) o;
117 int i =0;
118 for (Iterator iterator = list.iterator(); iterator.hasNext();) {
119 Object value = iterator.next();
120 if (value instanceof Recipe) {
121 Recipe recipe = (Recipe) value;
122 try {
123 value = recipe.create(classLoader);
124 } catch (ConstructionException e) {
125 e.setPrependAttributeName("[" + type + " item " + i + "]");
126 throw e;
127 }
128 }
129 //noinspection unchecked
130 instance.add(value);
131 i++;
132 }
133 return instance;
134 }
135
136 private Class getType(ClassLoader classLoader) {
137 Class setType = null;
138 try {
139 setType = Class.forName(type, true, classLoader);
140 } catch (ClassNotFoundException e) {
141 throw new ConstructionException("Type class could not be found: " + type);
142 }
143 return setType;
144 }
145
146 public void add(Boolean value) {
147 if (value == null) throw new NullPointerException("value is null");
148 list.add(value);
149 }
150
151 public void add(Character value) {
152 if (value == null) throw new NullPointerException("value is null");
153 list.add(value);
154 }
155
156 public void add(Byte value) {
157 if (value == null) throw new NullPointerException("value is null");
158 list.add(value);
159 }
160
161 public void add(Short value) {
162 if (value == null) throw new NullPointerException("value is null");
163 list.add(value);
164 }
165
166 public void add(Integer value) {
167 if (value == null) throw new NullPointerException("value is null");
168 list.add(value);
169 }
170
171 public void add(Long value) {
172 if (value == null) throw new NullPointerException("value is null");
173 list.add(value);
174 }
175
176 public void add(Float value) {
177 if (value == null) throw new NullPointerException("value is null");
178 list.add(value);
179 }
180
181 public void add(Double value) {
182 if (value == null) throw new NullPointerException("value is null");
183 list.add(value);
184 }
185
186 public void add(String value) {
187 if (value == null) throw new NullPointerException("value is null");
188 list.add(value);
189 }
190
191 public void add(Recipe value) {
192 if (value == null) throw new NullPointerException("value is null");
193 list.add(value);
194 }
195
196 public void addAll(Collection value) {
197 if (value == null) throw new NullPointerException("value is null");
198 for (Iterator iterator = value.iterator(); iterator.hasNext();) {
199 Object o = iterator.next();
200 if (o instanceof Boolean) {
201 add((Boolean)o);
202 } else if (o instanceof Character) {
203 add((Character)o);
204 } else if (o instanceof Byte) {
205 add((Byte)o);
206 } else if (o instanceof Short) {
207 add((Short)o);
208 } else if (o instanceof Integer) {
209 add((Integer)o);
210 } else if (o instanceof Long) {
211 add((Long)o);
212 } else if (o instanceof Float) {
213 add((Float)o);
214 } else if (o instanceof Double) {
215 add((Double)o);
216 } else if (o instanceof String) {
217 add((String)o);
218 } else if (o instanceof Recipe) {
219 add((Recipe)o);
220 } else {
221 add(new ValueRecipe(o));
222 }
223 }
224 }
225
226 }