001    /*
002      Copyright (C) 2002-2003 Laurent Martelli <laurent@aopsys.com>
003                              Renaud Pawlak <renaud@aopsys.com>
004    
005      This program is free software; you can redistribute it and/or modify
006      it under the terms of the GNU Lesser General Public License as
007      published by the Free Software Foundation; either version 2 of the
008      License, or (at your option) any later version.
009    
010      This program is distributed in the hope that it will be useful,
011      but WITHOUT ANY WARRANTY; without even the implied warranty of
012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013      GNU Lesser General Public License for more details.
014    
015      You should have received a copy of the GNU Lesser General Public License
016      along with this program; if not, write to the Free Software
017      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
018    
019    package org.objectweb.jac.aspects.persistence;
020    
021    import org.apache.log4j.Logger;
022    import org.objectweb.jac.core.AspectComponent;
023    import org.objectweb.jac.core.Wrappee;
024    import org.objectweb.jac.core.Wrapper;
025    import org.objectweb.jac.core.Wrapping;
026    import org.objectweb.jac.core.rtti.ClassItem;
027    import org.objectweb.jac.core.rtti.FieldItem;
028    import org.objectweb.jac.util.ExtArrays;
029    
030    /**
031     * This wrapper defines persistence extensions for objects that a
032     * defined persitent by a persistent aspect component. */
033    
034    public abstract class AbstractPersistenceWrapper extends Wrapper {
035    
036        static Logger logger = Logger.getLogger("persistence");
037    
038            public AbstractPersistenceWrapper(AspectComponent ac) {
039                    super(ac);
040            }
041    
042            public static final String ATTR_ADDED = "persistence.added";
043    
044            static boolean isWrapped(Wrappee wrappee, FieldItem field) {
045                    Object value = field.get(wrappee);
046                    if (value instanceof Wrappee
047                            && Wrapping.isExtendedBy(
048                                    (Wrappee) value,
049                                    null,
050                                    CollectionWrapper.class)) {
051                            logger.debug(field + " is wrapped");
052                            return true;
053                    } else {
054                            logger.debug(field + " is not wrapped");
055                            return false;
056                    }
057            }
058    
059            /**
060             * Gets the object in memory object for a "storage" value.
061             * @param value the "storage" value
062             * @return if value is an OID, a reference to the object with that
063             * OID is returned, otherwise, value is returned.
064             * @see #normalizeInput(Object)
065             */
066            public final Object normalizeOutput(Object value) throws Exception {
067                    if (value instanceof OID) {
068                            value = getAC().getObject((OID) value, null);
069                    }
070                    return value;
071            }
072    
073            /**
074             * Performs various stuff before storing a value in a storage. If
075             * the value is a Wrappee, it is made persistent.
076             * @param value the value to be stored
077             * @return if value is a wrappee, the OID of the object is
078             * returned, otherwise, value is returned.
079             * @see #normalizeInput(Object) 
080             */
081            public final Object normalizeInput(Object value) throws Exception {
082                    if (value != null) {
083                            logger.debug(
084                                    "normalizeInput(" + value.getClass().getName() + ")");
085                    }
086                    if (value instanceof Wrappee) {
087                            Wrappee wrappee = (Wrappee) value; // added object
088                            try {
089                                    Wrapping.invokeRoleMethod(
090                                            wrappee,
091                                            "makePersistent",
092                                            ExtArrays.emptyObjectArray);
093                            } catch (Exception e) {
094                                    e.printStackTrace();
095                            }
096    
097                            //PersistenceWrapper wrapper = getAC().makePersistent(wrappee);
098    
099                            if (getOID(wrappee) == null) {
100                                    // this should never happen
101                                    throw new InvalidOidException("oid is NULL,");
102                            }
103                            value = getOID(wrappee);
104                    } else {
105                            if (value != null) {
106                                    logger.debug(
107                                            value.getClass().getName() + " is not a wrappee");
108                            }
109                    }
110                    return value;
111            }
112    
113            public final OID getOID(Wrappee wrappee) {
114                    return getAC().getOID(wrappee);
115            }
116    
117            final void setOID(Wrappee wrappee, OID oid) {
118                    getAC().registerObject(oid, wrappee);
119            }
120    
121            /**
122             * Tells if the current object is persistent (role method).
123             *
124             * @return true if persistent 
125         */
126            public final boolean isPersistent(Wrappee wrappee) {
127                    return getOID(wrappee) != null;
128            }
129    
130        /**
131         * Returns the storage for a given class
132         *
133         * @param cli a class
134         * @return the storage of the class, or null.
135         */
136            public final Storage getStorage(ClassItem cli) {
137                    try {
138                            return getAC().getStorage(cli);
139                    } catch (Exception e) {
140                            logger.error("getStorage failed "+cli.getName(),e);
141                            return null;
142                    }
143            }
144    
145            public final PersistenceAC getAC() {
146                    return (PersistenceAC) getAspectComponent();
147            }
148    
149            public final void checkOid(Wrappee wrappee) throws InvalidOidException {
150                    if (getOID(wrappee) == null)
151                            throw new InvalidOidException("oid is NULL");
152            }
153    
154            public static class InvalidOidException extends RuntimeException {
155                    public InvalidOidException(String msg) {
156                            super(msg);
157                    }
158            }
159    }