001 /* 002 Copyright (C) 2002-2003 Laurent Martelli <laurent@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 /** 019 * ListWrapper.java 020 * 021 * 022 * Created: Sat Oct 13 16:14:15 2001 023 * 024 * @author <a href="mailto: "Laurent Martelli</a> 025 * @version 026 */ 027 028 package org.objectweb.jac.aspects.persistence; 029 030 import java.util.Arrays; 031 import java.util.Collection; 032 import java.util.Iterator; 033 import java.util.List; 034 import org.aopalliance.intercept.ConstructorInvocation; 035 import org.aopalliance.intercept.MethodInvocation; 036 import org.apache.log4j.Logger; 037 import org.objectweb.jac.core.AspectComponent; 038 import org.objectweb.jac.core.Interaction; 039 import org.objectweb.jac.core.Wrappee; 040 import org.objectweb.jac.core.Wrapping; 041 import org.objectweb.jac.core.rtti.ClassRepository; 042 import org.objectweb.jac.core.rtti.CollectionItem; 043 import org.objectweb.jac.core.rtti.MethodItem; 044 import org.objectweb.jac.util.ExtBoolean; 045 046 /** 047 * A wrapper for the list interface. 048 */ 049 public class ListWrapper extends CollectionWrapper { 050 static Logger logger = Logger.getLogger("persistence"); 051 052 public ListWrapper(AspectComponent ac, 053 Object substance, 054 CollectionItem collection, 055 boolean isLoaded) 056 { 057 super(ac, substance, collection, isLoaded); 058 } 059 060 protected void doLoad(Wrappee wrappee) throws Exception { 061 OID oid = getOID(wrappee); 062 List list = oid.getStorage().getList(oid); 063 MethodItem add = cr.getClass(wrappee).getMethod("add(java.lang.Object)"); 064 Object[] params = new Object[1]; 065 for (int i=0; i<list.size(); i++) { 066 try { 067 //list.set(i, normalizeOutput(list.get(i))); 068 params[0] = convert(normalizeOutput(list.get(i)),wrappee); 069 Wrapping.invokeOrg(wrappee, add, params); 070 } catch (NoSuchOIDError e) { 071 logger.error( 072 "ListWrapper.doLoad(" 073 + oid + "): "+collection.getName()+ 074 ": skipping item "+i+" with unknown OID " + list.get(i)); 075 list.set(i, null); 076 } catch (Exception e) { 077 logger.error( 078 "ListWrapper.doLoad(" 079 + oid + "): "+collection.getName()+ 080 ": skipping item "+i+" because of exception",e); 081 list.set(i, null); 082 } 083 } 084 /* 085 attrdef(ATTR_ADDED, "true"); 086 // Keep the number of dynamic invocations to the minimum 087 Wrapping.invokeOrg(wrappee, "addAll", new Object[] { list }); 088 attrdef(ATTR_ADDED, null); 089 */ 090 } 091 092 public Object contains(Interaction interaction) throws Exception { 093 if (isLoaded) { 094 return interaction.proceed(); 095 } else { 096 OID oid = getOID(interaction.wrappee); 097 return ExtBoolean.valueOf( 098 oid.getStorage().listContains( 099 oid, 100 normalizeInput(interaction.args[0]))); 101 } 102 } 103 104 public Object add(Interaction interaction) throws Exception { 105 logger.debug("adding " + interaction.args[0] 106 + " to list " + getOID(interaction.wrappee)); 107 Object result = Boolean.TRUE; 108 if (isLoaded) 109 result = interaction.proceed(); 110 111 OID oid = getOID(interaction.wrappee); 112 if (interaction.args.length == 1) { 113 // add(Object o) 114 oid.getStorage().addToList( 115 oid, 116 normalizeInput(interaction.args[0])); 117 } else if (interaction.args.length == 2) { 118 // add(int index, Object o) 119 oid.getStorage().addToList( 120 oid, 121 ((Integer) interaction.args[0]).longValue(), 122 normalizeInput(interaction.args[1])); 123 } 124 return result; 125 } 126 127 public Object addAll(Interaction interaction) throws Exception { 128 logger.debug("adding " + interaction.args[0] 129 + " to list " + getOID(interaction.wrappee)); 130 Object result = Boolean.TRUE; 131 if (isLoaded) 132 result = interaction.proceed(); 133 if (interaction.args.length==1) { 134 // addAll(Collection c) 135 Iterator i = ((Collection)interaction.args[0]).iterator(); 136 OID cid = getOID(interaction.wrappee); 137 Storage storage = cid.getStorage(); 138 while (i.hasNext()) { 139 storage.addToList( 140 cid, normalizeInput(i.next())); 141 } 142 } else { 143 // addAll(int index, Collection c) 144 Iterator i = ((Collection)interaction.args[0]).iterator(); 145 OID cid = getOID(interaction.wrappee); 146 long index = ((Integer) interaction.args[0]).longValue(); 147 Storage storage = cid.getStorage(); 148 while (i.hasNext()) { 149 storage.addToList( 150 cid, index++, normalizeInput(i.next())); 151 } 152 } 153 return result; 154 } 155 156 public Object get(Interaction interaction) throws Exception { 157 touch(); 158 if (isLoaded) { 159 return interaction.proceed(); 160 } else { 161 OID oid = getOID(interaction.wrappee); 162 return normalizeOutput( 163 oid.getStorage().getListItem( 164 oid, 165 ((Integer) interaction.args[0]).longValue())); 166 } 167 } 168 169 public Object remove(Interaction interaction) throws Exception { 170 touch(); 171 logger.debug("remove : "+ interaction.wrappee 172 + "," + Arrays.asList(interaction.args)); 173 Object result = null; 174 if (isLoaded) { 175 result = interaction.proceed(); 176 } else { 177 // WRONG!!! 178 result = Boolean.TRUE; 179 } 180 logger.debug("proceeded"); 181 OID oid = getOID(interaction.wrappee); 182 if (interaction.args[0] instanceof Integer) { 183 logger.debug("remove position"); 184 oid.getStorage().removeFromList( 185 oid, 186 ((Integer) interaction.args[0]).longValue()); 187 } else { 188 logger.debug("remove value"); 189 oid.getStorage().removeFromList( 190 oid, 191 normalizeInput(interaction.args[0])); 192 } 193 logger.debug("value removed"); 194 return result; 195 } 196 197 public Object removeRange(Interaction interaction) throws Exception { 198 // removeRange(int fromIndex, int toIndex) 199 touch(); 200 if (isLoaded) { 201 interaction.proceed(); 202 } 203 int from = ((Integer)interaction.args[0]).intValue(); 204 int to = ((Integer)interaction.args[1]).intValue(); 205 int size = ((Integer)size(interaction)).intValue(); 206 if (to>size) 207 to = size; 208 OID cid = getOID(interaction.wrappee); 209 Storage storage = cid.getStorage(); 210 for (; from<to; from++) { 211 storage.removeFromList(cid,from); 212 } 213 return null; 214 } 215 216 /** 217 * Remove all instances from the collection 218 */ 219 public Object clear(Interaction interaction) throws Exception { 220 touch(); 221 logger.debug("clear"); 222 Object result = interaction.proceed(); 223 OID oid = getOID(interaction.wrappee); 224 oid.getStorage().clearList(oid); 225 return result; 226 } 227 228 public Object set(Interaction interaction) throws Exception { 229 touch(); 230 if (isLoaded()) 231 interaction.proceed(); 232 OID oid = getOID(interaction.wrappee); 233 oid.getStorage().setListItem( 234 oid, 235 ((Integer) interaction.args[0]).intValue(), 236 interaction.args[1]); 237 return null; 238 } 239 240 public Object indexOf(Interaction interaction) throws Exception { 241 touch(); 242 if (isLoaded) { 243 return interaction.proceed(); 244 } else { 245 OID oid = getOID(interaction.wrappee); 246 return new Integer( 247 new Long( 248 oid.getStorage().getIndexInList( 249 oid, 250 normalizeInput(interaction.args[0]))) 251 .intValue()); 252 } 253 } 254 255 public Object lastIndexOf(Interaction interaction) throws Exception { 256 touch(); 257 if (isLoaded) { 258 return interaction.proceed(); 259 } else { 260 OID oid = getOID(interaction.wrappee); 261 return new Integer( 262 new Long( 263 oid.getStorage().getLastIndexInList( 264 oid, 265 normalizeInput(interaction.args[0]))) 266 .intValue()); 267 } 268 } 269 270 protected long getCollectionSize(OID oid) throws Exception { 271 return oid.getStorage().getListSize(oid); 272 } 273 274 public Object iterator(Interaction interaction) { 275 touch(); 276 return new ListIterator(interaction.wrappee); 277 } 278 279 public Object invoke(MethodInvocation invocation) throws Throwable { 280 String name = invocation.getMethod().getName(); 281 Interaction interaction = (Interaction) invocation; 282 if (name.equals("iterator")) { 283 load(interaction.wrappee); 284 //return iterator(interaction); 285 return interaction.proceed(); 286 } else if (name.equals("isEmpty")) { 287 return isEmpty(interaction); 288 } else if (name.equals("size")) { 289 return size(interaction); 290 } else if (name.equals("get")) { 291 return get(interaction); 292 } else if (name.equals("indexOf")) { 293 return indexOf(interaction); 294 } else if (name.equals("lastIndexOf")) { 295 return lastIndexOf(interaction); 296 } else if (name.equals("clear")) { 297 return clear(interaction); 298 } else if (name.equals("set")) { 299 return set(interaction); 300 } else if (name.equals("add")) { 301 return add(interaction); 302 } else if (name.equals("addAll")) { 303 return addAll(interaction); 304 } else if (name.equals("remove")) { 305 return remove(interaction); 306 } else if (name.equals("contains")) { 307 return contains(interaction); 308 } else if (name.equals("toArray")) { 309 load(interaction.wrappee); 310 return interaction.proceed(); 311 } else if (name.equals("clone")) { 312 load(interaction.wrappee); 313 return interaction.proceed(); 314 } else if (name.equals("removeRange")) { 315 return removeRange(interaction); 316 } else { 317 logger.error("ListWrapper: don't know what to do with method "+name); 318 } 319 return interaction.proceed(); 320 } 321 322 }