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.Iterator;
021    import java.util.Map;
022    import org.aopalliance.intercept.ConstructorInvocation;
023    import org.aopalliance.intercept.MethodInvocation;
024    import org.apache.log4j.Logger;
025    import org.objectweb.jac.core.AspectComponent;
026    import org.objectweb.jac.core.Interaction;
027    import org.objectweb.jac.core.Wrappee;
028    import org.objectweb.jac.core.Wrapping;
029    import org.objectweb.jac.core.rtti.ClassRepository;
030    import org.objectweb.jac.core.rtti.CollectionItem;
031    import org.objectweb.jac.core.rtti.MethodItem;
032    import org.objectweb.jac.util.ExtBoolean;
033    import org.objectweb.jac.util.Log;
034    
035    /**
036     * A wrapper for the Map interface.
037     */
038    public class MapWrapper extends CollectionWrapper {
039        static Logger logger = Logger.getLogger("persistence");
040    
041        public MapWrapper(AspectComponent ac, 
042                          Object substance,    
043                          CollectionItem collection, 
044                          boolean isLoaded) 
045        {
046            super(ac, substance, collection, isLoaded);
047        }
048    
049        protected void doLoad(Wrappee wrappee) throws Exception {
050            OID oid = getOID(wrappee);
051            Map map = oid.getStorage().getMap(oid);
052            // Keep the number of dynamic invocations to the minimum
053            //HashMap normalizedMap = new HashMap(map.size());
054            Iterator i = map.entrySet().iterator();
055            Object[] params = new Object[2];
056            MethodItem put = cr.getClass(wrappee).getMethod("put");
057            while (i.hasNext()) {
058                Map.Entry entry = (Map.Entry) i.next();
059                try {
060                    /*
061                      normalizedMap.put(
062                        normalizeOutput(entry.getKey()),
063                        normalizeOutput(entry.getValue()));
064                    */
065                    params[0] = normalizeOutput(entry.getKey());
066                    params[1] = normalizeOutput(entry.getValue());
067                    Wrapping.invokeOrg(wrappee, put, params);                
068                } catch (NoSuchOIDError e) {
069                    logger.error(
070                        "MapWrapper.doLoad("
071                            + oid + "): skipping entry with unknown OID " + entry);
072                }
073            }
074            /*
075            attrdef(ATTR_ADDED, "true");
076            Wrapping.invokeOrg(wrappee, "putAll", new Object[] { normalizedMap });
077            attrdef(ATTR_ADDED, null);
078            */
079        }
080    
081        public Object containsKey(Interaction interaction) throws Exception {
082            touch();
083            if (isLoaded) {
084                return interaction.proceed();
085            } else {
086                OID oid = getOID(interaction.wrappee);
087                return ExtBoolean.valueOf(
088                    oid.getStorage().mapContainsKey(
089                        oid,
090                        normalizeInput(interaction.args[0])));
091            }
092        }
093    
094        public Object containsValue(Interaction interaction) throws Exception {
095            touch();
096            if (isLoaded) {
097                return interaction.proceed();
098            } else {
099                OID oid = getOID(interaction.wrappee);
100                return ExtBoolean.valueOf(
101                    oid.getStorage().mapContainsValue(
102                        oid,
103                        normalizeInput(interaction.args[0])));
104            }
105        }
106    
107        public Object put(Interaction interaction) throws Exception {
108            touch();
109            Object ret = null;
110            if (isLoaded)
111                interaction.proceed();
112            OID oid = getOID(interaction.wrappee);
113            ret =
114                normalizeOutput(
115                    oid.getStorage().putInMap(
116                        oid,
117                        normalizeInput(interaction.args[0]),
118                        normalizeInput(interaction.args[1])));
119            return ret;
120        }
121    
122        public Object get(Interaction interaction) throws Exception {
123            touch();
124            if (isLoaded) {
125                return interaction.proceed();
126            } else {
127                OID oid = getOID(interaction.wrappee);
128                return normalizeOutput(
129                    oid.getStorage().getFromMap(
130                        oid,
131                        normalizeInput(interaction.args[0])));
132            }
133        }
134    
135        public Object remove(Interaction interaction) throws Exception {
136            touch();
137            Object result1 = null;
138            boolean proceeded = false;
139            if (isLoaded) {
140                result1 = interaction.proceed();
141                proceeded = true;
142            }
143            OID oid = getOID(interaction.wrappee);
144            Object result2 =
145                oid.getStorage().removeFromMap(
146                    oid,
147                    normalizeInput(interaction.args[0]));
148            if (proceeded)
149                return result1;
150            else
151                return normalizeOutput(result2);
152        }
153    
154        /**
155         * Remove all instances from the collection
156         */
157        public Object clear(Interaction interaction) throws Exception {
158            touch();
159            Object result = interaction.proceed();
160            OID oid = getOID(interaction.wrappee);
161            oid.getStorage().clearMap(oid);
162            return result;
163        }
164    
165        protected long getCollectionSize(OID oid) throws Exception {
166            return oid.getStorage().getMapSize(oid);
167        }
168    
169        public Object iterator(Interaction interaction) {
170            touch();
171            return new MapIterator(interaction.wrappee);
172        }
173    
174        public Object invoke(MethodInvocation invocation) throws Throwable {
175            String name = invocation.getMethod().getName();
176            Interaction interaction = (Interaction) invocation;
177            if (name.equals("keySet")) {
178                load(interaction.wrappee);
179                return interaction.proceed();
180            } else if (name.equals("entrySet")) {
181                load(interaction.wrappee);
182                return interaction.proceed();
183            } else if (name.equals("values")) {
184                load(interaction.wrappee);
185                return interaction.proceed();
186            } else if (name.equals("isEmpty")) {
187                return isEmpty(interaction);
188            } else if (name.equals("size")) {
189                return size(interaction);
190            } else if (name.equals("containsKey")) {
191                return containsKey(interaction);
192            } else if (name.equals("containsValue")) {
193                return containsValue(interaction);
194            } else if (name.equals("clear")) {
195                return clear(interaction);
196            } else if (name.equals("put")) {
197                return put(interaction);
198            } else if (name.equals("remove")) {
199                return remove(interaction);
200            } else if (name.equals("get")) {
201                return get(interaction);
202            } else if (name.equals("clone")) {
203                load(interaction.wrappee);
204                return interaction.proceed();
205            } else {
206                logger.error("MapWrapper: don't know what to do with method "+name);
207            }
208            return interaction.proceed();
209        }
210    
211    }