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 (read) for wrappees that perform
033     * read 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 ReadWrapper 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 ReadWrapper(
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            Object wrappee = interaction.wrappee;
083            String wrappeeName = names.getName(wrappee);        
084            
085            try {
086                            storage.load(wrappee,wrappeeName,ds);
087                    } catch (Exception e) {
088                            e.printStackTrace();
089                System.exit(1);
090                    }
091            
092            return proceed(interaction);
093        }
094            
095        
096        /**
097         * The reference towards the JAC name repository.
098         * Needed by applyPersistence().
099         */
100        private Repository names = NameRepository.get();
101    
102        public Object construct(ConstructorInvocation invocation)
103            throws Throwable {
104            throw new Exception("This wrapper does not support constructor wrapping");
105        }    
106    }