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;
019    
020    
021    import java.lang.reflect.InvocationTargetException;
022    import org.objectweb.jac.aspects.distrans.persistence.PersistenceAC;
023    import org.objectweb.jac.core.ACManager;
024    import org.objectweb.jac.core.AspectComponent;
025    import org.objectweb.jac.core.NameRepository;
026    import org.objectweb.jac.core.Wrapper;
027    import org.objectweb.jac.core.rtti.ClassItem;
028    import org.objectweb.jac.core.rtti.ClassRepository;
029    import org.objectweb.jac.util.Log;
030    import org.objectweb.jac.util.Repository;
031    
032    /**
033     * This AC implements some transactional behaviors for business methods.
034     * This AC relies:
035     * <ul>
036     * <li>on JOTM to perform distributed transactions</li>
037     * <li>on a AC implementing jac.aspects.distrans.persistence.PersistenceAC
038     *     to store persistent data involved into the transactions</li>
039     * </ul>
040     * 
041     * @author Lionel Seinturier <Lionel.Seinturier@lip6.fr>
042     * @version 1.0
043     */
044    public class DisTransAC extends AspectComponent {
045        
046        /** The PersistenceAC associated to this aspect. */
047        private PersistenceAC persistenceAC;
048    
049        public DisTransAC() {
050            
051            /**
052             * Check whether a AC implementing
053             * jac.aspects.distrans.persistence.PersistenceItf has been woven.
054             * DisTransAC relies on it to store persistence data involved in the
055             * transaction.
056             */
057            persistenceAC = null;
058    
059            ACManager acm = ACManager.getACM();
060            Object[] acs = acm.getObjects();
061            for (int i = 0; i < acs.length; i++) {
062                if ( acs[i] instanceof PersistenceAC )
063                    persistenceAC = (PersistenceAC)acs[i];
064                    }
065            
066            if ( persistenceAC == null )
067                throw new RuntimeException(
068                    "An AC implementing jac.aspects.distrans.persistence.PersistenceItf is mandatory for DisTransAC to work"
069                );
070        }
071        
072        
073        /**
074         * Delimit a transaction.
075         * The transaction will begin before the method designated by the pointcut
076         * designated by the 3 first parameter, and will end after the pointcut
077         * designated by the 3 last ones.
078         * 
079         * @param txid      the transaction identifier
080         * @param beginCNE  begin class name expression
081         * @param beginONE  begin object name expression
082         * @param beginMNE  begin method name expression
083         * @param endCNE    end class name expression
084         * @param endONE    end object name expression
085         * @param endMNE    end method name expression
086         * @param decisionClassName  the name of the class defining the method
087         *           for deciding whether the transaction is to be commited
088         *           or rollbacked.
089         *           This must be a subclass of EndTransactionWrapper. 
090         */
091        public void delimitTransaction(
092            String txid, 
093            String beginCNE, String beginONE, String beginMNE,
094            String endCNE, String endONE, String endMNE,
095            String decisionClassName ) {
096                
097            BeginTransactionWrapper beginwrapper =
098                new BeginTransactionWrapper(this);
099            
100            ClassItem cl = classes.getClass(decisionClassName);
101            
102            Wrapper endwrapper = null;
103                    try {
104                            endwrapper = (Wrapper)
105                                cl.newInstance(
106                                    new Class[]{AspectComponent.class},
107                                    new Object[]{this}
108                                );
109                    } catch (Exception e) {
110                Log.error("delimitTransaction: Failed to instanciate endwrapper "+decisionClassName);
111                            e.printStackTrace();
112                    }
113            pointcut(beginONE, beginCNE, beginMNE, beginwrapper, null);
114            pointcut(endONE, endCNE, endMNE, endwrapper, null);
115        }
116        
117            
118        /**
119         * The reference towards the JAC name repository.
120         * Needed by setFieldsValueFromDataSource().
121         */
122        private Repository names = NameRepository.get();
123    
124        /**
125         * The reference towards the RTTI class repository.
126         */
127        private ClassRepository classes = ClassRepository.get();
128    }