net.sf.taverna.t2.reference.impl.CacheAspect.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.taverna.t2.reference.impl.CacheAspect.java

Source

/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester   
 * 
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 * 
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *    
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *    
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.reference.impl;

import net.sf.taverna.t2.reference.DaoException;
import net.sf.taverna.t2.reference.Identified;
import net.sf.taverna.t2.reference.ReferenceServiceCacheProvider;
import net.sf.taverna.t2.reference.T2Reference;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * An aspect used to intercept calls to the various data access objects and
 * divert through a write-through cache provider
 * 
 * @author Tom Oinn
 */
public class CacheAspect {
    private ReferenceServiceCacheProvider cacheProvider;

    /**
     * Return an injected ReferenceServiceCacheProvider
     */
    private final ReferenceServiceCacheProvider getCacheProvider() {
        return cacheProvider;
    }

    /**
     * Inject an instance of ReferenceServiceCacheProvider
     * 
     * @param cacheProvider
     *            the cache provider to use
     */
    public final void setCacheProvider(final ReferenceServiceCacheProvider cacheProvider) {
        this.cacheProvider = cacheProvider;
    }

    /**
     * Handle a 'get by T2Reference' operation on a Dao
     * 
     * @param pjp
     *            the join point representing the ongoing method call to the dao
     * @return the entity identified by the T2Reference supplied to the method
     *         to which this advice applies
     * @throws DaoException
     *             if anything goes wrong
     */
    public final Identified getObject(final ProceedingJoinPoint pjp) throws DaoException {
        Identified result = null;

        // Get the T2Reference from the argument to the get method
        T2Reference id = (T2Reference) pjp.getArgs()[0];
        if (id != null) {
            result = getCacheProvider().get(id);
            if (result != null)
                return result;
        }
        // If we miss the cache then call the method as usual
        try {
            result = (Identified) pjp.proceed();
        } catch (DaoException e) {
            throw e;
        } catch (Throwable e) {
            throw new DaoException("Unexpected exception type during aspect " + "based invocation", e);
        }

        // Write back to the cache
        if (result != null)
            getCacheProvider().put(result);

        return result;
    }

    /**
     * Called around a write or update operation on the backing store, writes
     * through to the cache after modifying the state of the backing store and
     * before returning from the dao method
     * 
     * @param pjp
     *            join point representing the ongoing method invocation to cache
     * @throws DaoException
     *             if anything goes wrong
     */
    public void putObject(final ProceedingJoinPoint pjp) throws DaoException {
        // Get the Identified being stored by the method we're advising
        Identified storedObject = (Identified) pjp.getArgs()[0];

        try {
            // Run the store or update method
            pjp.proceed();
        } catch (DaoException e) {
            throw e;
        } catch (Throwable e) {
            throw new DaoException("Unexpected exception type during aspect " + "based invocation", e);
        }

        /*
         * Assuming the method isn't null and has an identifier (which it will
         * if we haven't thrown an exception before now) write it back to the
         * cache provider
         */
        if (storedObject != null && storedObject.getId() != null)
            getCacheProvider().put(storedObject);
    }
}