001    /*
002      Copyright (C) 2001-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    package org.objectweb.jac.aspects.persistence;
019    
020    import java.util.List;
021    import org.aopalliance.intercept.ConstructorInvocation;
022    import org.aopalliance.intercept.MethodInvocation;
023    import org.apache.log4j.Logger;
024    import org.objectweb.jac.core.AspectComponent;
025    import org.objectweb.jac.core.Interaction;
026    import org.objectweb.jac.core.Wrappee;
027    import org.objectweb.jac.core.Wrapping;
028    import org.objectweb.jac.core.rtti.ClassRepository;
029    import org.objectweb.jac.core.rtti.CollectionItem;
030    import org.objectweb.jac.core.rtti.MethodItem;
031    import org.objectweb.jac.util.ExtBoolean;
032    
033    /**
034     * A wrapper for the Set interface.
035     */
036    public class SetWrapper extends CollectionWrapper {
037        static Logger logger = Logger.getLogger("persistence");
038    
039        public SetWrapper(AspectComponent ac, 
040                          Object substance,
041                          CollectionItem collection,
042                          boolean isLoaded) 
043        {
044            super(ac, substance, collection, isLoaded);
045        }
046    
047        protected void doLoad(Wrappee wrappee) throws Exception {
048            logger.debug( "do load " + wrappee.getClass());
049            // Keep the number of dynamic invocations to the minimum
050            OID oid = getOID(wrappee);
051            List list = oid.getStorage().getSet(oid);
052            MethodItem add = cr.getClass(wrappee).getMethod("add(java.lang.Object)");
053            Object[] params = new Object[1];
054            for (int i = 0; i < list.size(); i++) {
055                try {
056                    //list.set(i, normalizeOutput(list.get(i)));
057                    params[0] = convert(normalizeOutput(list.get(i)),wrappee);
058                    Wrapping.invokeOrg(wrappee, add, params);
059                } catch (NoSuchOIDError e) {
060                    logger.error(
061                        "SetWrapper.doLoad("
062                        + oid + "): "+collection.getName()
063                        + ": skipping object at pos "+i
064                        +" with unknown OID "+list.get(i));
065                    list.set(i, null);
066                } catch (Exception e) {
067                    logger.error(
068                        "SetWrapper.doLoad("
069                        + oid + "): "+collection.getName()
070                        +"skipping object at pos "+i
071                        +" because of exception",e);
072                    list.set(i, null);
073                }
074            }
075            /*
076            attrdef(ATTR_ADDED, "true");
077            Wrapping.invokeOrg(wrappee, "addAll", new Object[] { list });
078            attrdef(ATTR_ADDED, null);
079            */
080        }
081    
082        public Object contains(Interaction interaction) throws Exception {
083            touch();
084            if (isLoaded) {
085                return interaction.proceed();
086            } else {
087                OID oid = getOID(interaction.wrappee);
088                return ExtBoolean.valueOf(
089                    oid.getStorage().setContains(
090                        oid,
091                        normalizeInput(interaction.args[0])));
092            }
093        }
094    
095        public boolean add(Interaction interaction) throws Exception {
096            touch();
097            if (interaction.args[0] != null)
098                logger.debug(
099                    "adding "
100                        + interaction.args[0].getClass().getName()
101                        + " to set");
102            if (isLoaded)
103                interaction.proceed();
104            OID oid = getOID(interaction.wrappee);
105            return oid.getStorage().addToSet(
106                oid,
107                normalizeInput(interaction.args[0]));
108        }
109    
110        public Object remove(Interaction interaction) throws Exception {
111            touch();
112            boolean result1 = false;
113            if (isLoaded) {
114                result1 = ((Boolean) interaction.proceed()).booleanValue();
115            }
116            OID oid = getOID(interaction.wrappee);
117            boolean result2 =
118                oid.getStorage().removeFromSet(
119                    oid,
120                    normalizeInput(interaction.args[0]));
121            if (isLoaded) {
122                if (result1 != result2)
123                    throw new Error("SetWrapper.remove result1 != result2");
124                return ExtBoolean.valueOf(result1);
125            } else {
126                return ExtBoolean.valueOf(result2);
127            }
128        }
129    
130        /**
131         * Remove all instances from the collection
132         */
133        public Object clear(Interaction interaction) throws Exception {
134            touch();
135            Object result = interaction.proceed();
136            OID oid = getOID(interaction.wrappee);
137            oid.getStorage().clearSet(oid);
138            return result;
139        }
140    
141        protected long getCollectionSize(OID oid) throws Exception {
142            return oid.getStorage().getSetSize(oid);
143        }
144    
145        public Object iterator(Interaction interaction) {
146            touch();
147            return new SetIterator(interaction.wrappee);
148        }
149    
150        public Object invoke(MethodInvocation invocation) throws Throwable {
151            String name = invocation.getMethod().getName();
152            Interaction interaction = (Interaction) invocation;
153            if (name.equals("iterator")) {
154                load(interaction.wrappee);
155                return interaction.proceed();
156            } else if (name.equals("isEmpty")) {
157                return isEmpty(interaction);
158            } else if (name.equals("size")) {
159                return size(interaction);
160            } else if (name.equals("clear")) {
161                return clear(interaction);
162            } else if (name.equals("add")) {
163                return new Boolean(add(interaction));
164            } else if (name.equals("remove")) {
165                return remove(interaction);
166            } else if (name.equals("contains")) {
167                return contains(interaction);
168            } else if (name.equals("toArray")) {
169                load(interaction.wrappee);
170                return interaction.proceed();
171            } else if (name.equals("clone")) {
172                load(interaction.wrappee);
173                return interaction.proceed();
174            } else {
175                logger.error("SetWrapper: don't know what to do with method "+name);
176            }
177            return interaction.proceed();
178        }
179    
180    }