001 /* 002 Copyright (C) 2001-2002 Renaud Pawlak <renaud@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.synchronization; 019 020 import org.aopalliance.intercept.ConstructorInvocation; 021 import org.aopalliance.intercept.MethodInvocation; 022 import org.apache.log4j.Logger; 023 import org.objectweb.jac.core.AspectComponent; 024 import org.objectweb.jac.core.Interaction; 025 import org.objectweb.jac.core.Wrapper; 026 import org.objectweb.jac.util.Log; 027 import org.objectweb.jac.util.Semaphore; 028 029 /** 030 * This aspect component allows the programmer to synchronize a set of 031 * methods on different objects or classes in a centralized way (do 032 * not use the synchronized java keyword anymore). 033 * 034 * <p>The monitor implementation to provide synchronization is 035 * implemented by a semaphore. 036 * 037 * @see org.objectweb.jac.util.Semaphore */ 038 039 public class SynchronizationAC 040 extends AspectComponent 041 implements SynchronizationConf { 042 043 static Logger logger = Logger.getLogger("synchronization"); 044 045 public void synchronize(String classes, String methods, String objects) { 046 pointcut( 047 objects, 048 classes, 049 methods, 050 new SynchronizationWrapper(this), 051 null); 052 } 053 054 /** 055 * This inner wrapper implements the methods synchronization with a 056 * semaphore. */ 057 058 public class SynchronizationWrapper extends Wrapper { 059 // one resource is available by default 060 // (only on thread can enter) 061 Semaphore semaphore = new Semaphore(1); 062 063 public SynchronizationWrapper(AspectComponent ac) { 064 super(ac); 065 } 066 067 public Object synchronize(Interaction interaction) { 068 Object ret = null; 069 logger.debug(interaction.wrappee 070 + " acquires semaphore for " 071 + interaction.method); 072 semaphore.acquire(); 073 try { 074 proceed(interaction); 075 } finally { 076 logger.debug(interaction.wrappee 077 + " releases semaphore for " 078 + interaction.method); 079 semaphore.release(); 080 } 081 return ret; 082 } 083 084 public Object invoke(MethodInvocation invocation) throws Throwable { 085 return synchronize((Interaction) invocation); 086 } 087 088 public Object construct(ConstructorInvocation invocation) 089 throws Throwable { 090 return synchronize((Interaction) invocation); 091 } 092 093 } 094 }