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 }