001    /*
002      Copyright (C) 2001-2003 Lionel Seinturier <Lionel.Seinturier@lip6.fr>
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.distrans.persistence;
019    
020    import org.enhydra.jdbc.standard.StandardXADataSource;
021    
022    import org.objectweb.jac.core.AspectComponent;
023    import org.objectweb.jac.core.Interaction;
024    import org.objectweb.jac.core.NameRepository;
025    import org.objectweb.jac.core.Wrapper;
026    import org.objectweb.jac.util.Repository;
027    
028    import org.aopalliance.intercept.ConstructorInvocation;
029    import org.aopalliance.intercept.MethodInvocation;
030    
031    /**
032     * This class define a wrapping method (write) for wrappees that perform
033     * write operations on transactional ressources.
034     * This wrapper may wrap several wrappees from different classes.
035     * Each wrappee field is mapped onto a SQL table attribute.
036     * The SQL tables contain one more attribute which is the name of the wrappee,
037     * and which is also the primary key of the table.
038     * 
039     * @author Lionel Seinturier <Lionel.Seinturier@lip6.fr>
040     * @version 1.0
041     */
042    public class WriteWrapper extends Wrapper {
043    
044        /**
045         * The instance implementing the technical API for persistence.
046         * SimpleDbPersistence implements it.
047         */
048        private PersistenceItf storage;
049        
050        /**
051         * The data source used to open a connection towards the database
052         * where the data is stored.
053         */
054        private StandardXADataSource ds;
055        
056        /**
057         * @param ac       the AC managing this wrapper
058         * @param storage  the technical instance for persistence
059         * @param ds       the data source used to create a connection towards
060         *                 the database where the data is stored
061         */
062        public WriteWrapper(
063            AspectComponent ac, PersistenceItf storage, StandardXADataSource ds ) {
064            
065            super(ac);
066            this.storage = storage;
067            this.ds = ds;
068        }
069        
070        /**
071         * Wrapping method for wrappees that perform
072         * write operations on transactional ressources.
073         * After proceeding the interaction, fields value are saved
074         * into the database.
075         * Fetching (ie reading) the data before, is a way to let the database
076         * manage the blocking mechanism whenever concurrent transactions occur.
077         */
078            public Object invoke(MethodInvocation invocation) throws Throwable {
079            
080            Interaction interaction = (Interaction) invocation;
081    
082            /** Proceed the interaction. */        
083            Object ret = proceed(interaction);
084            
085            Object wrappee = interaction.wrappee;
086            String wrappeeName = names.getName(wrappee);        
087            
088            try {
089                storage.store(wrappee,wrappeeName,ds);
090            } catch (Exception e) {
091                e.printStackTrace();
092                System.exit(1);
093            }
094    
095            return ret;
096        }
097        
098        
099        /**
100         * The reference towards the JAC name repository.
101         * Needed by applyPersistence().
102         */
103        private Repository names = NameRepository.get();
104        
105        public Object construct(ConstructorInvocation invocation)
106            throws Throwable {
107            throw new Exception("This wrapper does not support constructor wrapping");
108        }    
109    }