Add missing import.

Add missing import.

/*
 * Copyright (C) 2011 Archie L. Cobbs. All rights reserved.
 *
 * $Id: SpringContextApplication.java 160 2011-10-24 18:00:49Z archie.cobbs $
 */

package org.dellroad.stuff.vaadin;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect;
import org.springframework.beans.factory.aspectj.ConfigurableObject;

/**
 * Aspect that autowires classes marked with the Spring's {@link Configurable @Configurable} annotation to a
 * {@link SpringContextApplication} application context.
 *
 *

 * This aspect does the same thing that Spring's {@code AnnotationBeanConfigurerAspect} aspect does,
 * except that this aspect configures beans using the application context associated with the current
 * {@link SpringContextApplication} Vaadin application rather than the one associated with the overall
 * servlet context (i.e., its parent).
 *

 *
 *

 * As a result, objects so annotated will be configured for their specific {@link SpringContextApplication}
 * instance, and therefore can only be instantiated by threads associated with a current {@link SpringContextApplication}
 * (see {@link ContextApplication#get}). This will be the case when executing within a {@link SpringContextApplication}
 * Vaadin application HTTP request or an invocation of {@link ContextApplication#invoke} on same.
 *

 *
 *

 * This implementation is derived from Spring's {@code AnnotationBeanConfigurerAspect} implementation
 * and therefore shares its license (also Apache).
 *

 *
 * @see SpringContextApplication
 * @see ContextApplication#get
 * @see Configurable
 */
public aspect VaadinConfigurableAspect extends AbstractInterfaceDrivenDependencyInjectionAspect {

	public pointcut inConfigurableBean() : @this(Configurable);

	public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);

	declare parents: @Configurable * implements ConfigurableObject;

    @Override
	public void configureBean(Object bean) {
        SpringContextApplication.get().getBeanConfigurerSupport().configureBean(bean);
    }

	private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if(c.preConstruction());
}

/*
 * Copyright (C) 2011 Archie L. Cobbs. All rights reserved.
 *
 * $Id: SpringContextApplication.java 160 2011-10-24 18:00:49Z archie.cobbs $
 */

package org.dellroad.stuff.vaadin;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect;

/**
 * Aspect that autowires classes marked with the Spring's {@link Configurable @Configurable} annotation to a
 * {@link SpringContextApplication} application context.
 *
 *

 * This aspect does the same thing that Spring's {@code AnnotationBeanConfigurerAspect} aspect does,
 * except that this aspect configures beans using the application context associated with the current
 * {@link SpringContextApplication} Vaadin application rather than the one associated with the overall
 * servlet context (i.e., its parent).
 *

 *
 *

 * As a result, objects so annotated will be configured for their specific {@link SpringContextApplication}
 * instance, and therefore can only be instantiated by threads associated with a current {@link SpringContextApplication}
 * (see {@link ContextApplication#get}). This will be the case when executing within a {@link SpringContextApplication}
 * Vaadin application HTTP request or an invocation of {@link ContextApplication#invoke} on same.
 *

 *
 *

 * This implementation is derived from Spring's {@code AnnotationBeanConfigurerAspect} implementation
 * and therefore shares its license (also Apache).
 *

 *
 * @see SpringContextApplication
 * @see ContextApplication#get
 * @see Configurable
 */
public aspect VaadinConfigurableAspect extends AbstractInterfaceDrivenDependencyInjectionAspect {

	public pointcut inConfigurableBean() : @this(Configurable);

	public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);

	declare parents: @Configurable * implements ConfigurableObject;

    @Override
	public void configureBean(Object bean) {
        SpringContextApplication.get().getBeanConfigurerSupport().configureBean(bean);
    }

	private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if(c.preConstruction());
}


XSKINX-43 Compatibility mapping to support skin file extensions move/rename with backward compatibility

Fixed missing reference to JIRA issue for the fullScreen script rename/move

git-svn-id: ace560153e38297b711cbd4c8e91a836d3f7586e@32593 f329d543-caf0-0310-9063-dda96c69346f

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This 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 software 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 software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.plugin.skinx;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

/**
 * Add a backward compatibility layer to the {@link com.xpn.xwiki.plugin.skinx.SkinFileExtensionPluginApi} class.
 *
 * @version $Id$
 */
public aspect SkinFileExtensionPluginApiCompatibilityAspect
{
    /**
     * Compatibility mapping that associates a deprecated resource file to its new relative path
     */
    private static Map<String, String> compatibilityMap = new HashMap<String, String>();

    static {
        // fullScreen script has been moved and renamed in XWiki 2.6RC2 / 2.7M1 See XWIKI-5659
        compatibilityMap.put("js/xwiki/editors/fullScreenEdit.js", "uicomponents/widgets/fullScreen.js");
        compatibilityMap.put("js/xwiki/editors/fullScreenEdit.css", "uicomponents/widgets/fullScreen.css");
    }

    /**
     * Pointcut that catches all skin file extensions "use" join points.
     */
    private pointcut sfxUse(String path) : execution(void SkinFileExtensionPluginApi.use(..)) && args(path, ..);

    /**
     * Advice around skin file extensions "use" join points, that checks if the requested file is declared in the map of
     * deprecated extensions paths. If it is, it logs a warning message in the console, and calls the skin extension
     * plugin with the new path, declared in the map.
     */
    void around(String path): sfxUse(path)
    {
        if (compatibilityMap.containsKey(path)) {

            Logger logger = Logger.getLogger(thisJoinPoint.getSignature().getDeclaringType());
            logger.warn(MessageFormat.format(
                "Skin file extension with path [{0}] is deprecated. Please use [{1}] instead.", new Object[] {path,
                    compatibilityMap.get(path)}));

            proceed(compatibilityMap.get(path));
        }

        proceed(path);
    }
}

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This 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 software 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 software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.plugin.skinx;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

/**
 * Add a backward compatibility layer to the {@link com.xpn.xwiki.plugin.skinx.SkinFileExtensionPluginApi} class.
 *
 * @version $Id$
 */
public aspect SkinFileExtensionPluginApiCompatibilityAspect
{
    /**
     * Compatibility mapping that associates a deprecated resource file to its new relative path
     */
    private static Map<String, String> compatibilityMap = new HashMap<String, String>();

    static {
        // fullScreen script has been moved and renamed in XWiki 2.6RC2 / 2.7M1 See
        compatibilityMap.put("js/xwiki/editors/fullScreenEdit.js", "uicomponents/widgets/fullScreen.js");
        compatibilityMap.put("js/xwiki/editors/fullScreenEdit.css", "uicomponents/widgets/fullScreen.css");
    }

    /**
     * Pointcut that catches all skin file extensions "use" join points.
     */
    private pointcut sfxUse(String path) : execution(void SkinFileExtensionPluginApi.use(..)) && args(path, ..);

    /**
     * Advice around skin file extensions "use" join points, that checks if the requested file is declared in the map of
     * deprecated extensions paths. If it is, it logs a warning message in the console, and calls the skin extension
     * plugin with the new path, declared in the map.
     */
    void around(String path): sfxUse(path)
    {
        if (compatibilityMap.containsKey(path)) {

            Logger logger = Logger.getLogger(thisJoinPoint.getSignature().getDeclaringType());
            logger.warn(MessageFormat.format(
                "Skin file extension with path [{0}] is deprecated. Please use [{1}] instead.", new Object[] {path,
                    compatibilityMap.get(path)}));

            proceed(compatibilityMap.get(path));
        }

        proceed(path);
    }
}


added license header

added license header

/**
 * palava - a java-php-bridge
 * Copyright (C) 2007-2010  CosmoCode GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 */

package de.cosmocode.palava.jta;

import javax.transaction.Status;
import javax.transaction.UserTransaction;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Provider;

import de.cosmocode.palava.core.aop.AbstractPalavaAspect;

public abstract aspect AbstractUserTransactionAspect extends AbstractPalavaAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractUserTransactionAspect.class);

    private Provider<UserTransaction> provider;

    @Inject
    void setProvider(Provider<UserTransaction> provider) {
        this.provider = Preconditions.checkNotNull(provider, "Provider");
    }

    protected abstract pointcut transactional();

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around() throws Exception: transactional() {
        final UserTransaction tx = provider.get();
        LOG.trace("Using transaction {}", tx);
        final boolean localTx = tx.getStatus() == Status.STATUS_NO_TRANSACTION;

        if (localTx) {
            LOG.trace("Beginning automatic transaction");
            tx.begin();
        } else {
            LOG.trace("Transaction already active");
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (RuntimeException e) {
            LOG.error("Exception inside automatic transaction context", e);
            tx.rollback();
            throw e;
        }

        try {
            if (localTx && tx.getStatus() == Status.STATUS_ACTIVE) {
                tx.commit();
                LOG.trace("Committed automatic transaction");
            }
            return returnValue;
        } catch (Exception e) {
            LOG.error("Commit in automatic transaction context failed", e);
            tx.rollback();
            throw e;
        }
    }

}


warning fixes

warning fixes

Signed-off-by: Ketoth Xupack <2ff7bd69a79a23dbf64ebd5846a612566f93fbf7@gmail.com>

package org.nohope.validation;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.aspectj.lang.reflect.MethodSignature;

import javax.annotation.Nonnull;
import javax.annotation.meta.When;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@SuppressWarnings({
        "StringBufferReplaceableByString",
        "UtilityClassWithoutPrivateConstructor"
})
public final aspect NotNullAspect {

    // searches for all methods have at last one parameter annotated with @Nonnull
    pointcut nonNullParameter():
            execution(* *.*(.., @javax.annotation.Nonnull (*), ..));

    // searches for all methods which returns any reference type and annotated with @Nonnull
    pointcut validatedReturnValue():
            execution(@javax.annotation.Nonnull Object+ *.*(..));

    @SuppressAjWarnings
    after() returning(final Object ret): validatedReturnValue() {
        final MethodSignature sig = (MethodSignature) thisJoinPoint.getSignature();
        if (ret == null) {
            throw new IllegalStateException(new StringBuilder("@Nonnull method ")
                    .append(toString(sig))
                    .append(" must not return null")
                    .toString()
            );
        }
    }

    @SuppressAjWarnings
    before(): nonNullParameter() {
        final MethodSignature sig = (MethodSignature) thisJoinPoint.getSignature();
        final Method method = sig.getMethod();
        final Annotation[][] annotations = method.getParameterAnnotations();

        int i = 1;
        for (final Object obj : thisJoinPoint.getArgs()) {
            Nonnull a = null;
            for (Annotation annotation : annotations[i - 1]) {
                if (annotation instanceof Nonnull) {
                    a = (Nonnull) annotation;
                    break;
                }
            }

            if (obj == null && a != null && a.when() == When.ALWAYS) {
                throw new IllegalArgumentException(new StringBuilder("Argument ")
                        .append(i)
                        .append(" for @Nonnull parameter of ")
                        .append(toString(sig))
                        .append(" must not be null")
                        .toString()
                );
            }
            i++;
        }
    }

    private static StringBuilder toString(final MethodSignature sig) {
        final Method method = sig.getMethod();
        final Class[] args = method.getParameterTypes();
        final StringBuilder builder = new StringBuilder();
        builder.append('\'')
               .append(method.getReturnType().getSimpleName())
               .append(" ")
               .append(sig.getDeclaringType().getCanonicalName())
               .append('.')
               .append(method.getName())
               .append('(');
        boolean started = true;
        for (final Class arg : args) {
            if (!started) {
                builder.append(", ");
            } else {
                started = false;
            }
            builder.append(arg.getCanonicalName());
        }
        builder.append(")'");
        return builder;
    }
}

package org.nohope.validation;

import org.aspectj.lang.reflect.MethodSignature;

import javax.annotation.Nonnull;
import javax.annotation.meta.When;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@SuppressWarnings({
        "StringBufferReplaceableByString",
        "UtilityClassWithoutPrivateConstructor"
})
public final aspect NotNullAspect {

    // searches for all methods have at last one parameter annotated with @Nonnull
    pointcut nonNullParameter():
            execution(* *.*(.., @javax.annotation.Nonnull (*), ..));

    // searches for all methods which returns any reference type and annotated with @Nonnull
    pointcut validatedReturnValue():
            execution(@javax.annotation.Nonnull Object+ *.*(..));

    after() returning(final Object ret): validatedReturnValue() {
        final MethodSignature sig = (MethodSignature) thisJoinPoint.getSignature();
        if (ret == null) {
            throw new IllegalStateException(new StringBuilder("@Nonnull method ")
                    .append(toString(sig))
                    .append(" must not return null")
                    .toString()
            );
        }
    }

    before(): nonNullParameter() {
        final MethodSignature sig = (MethodSignature) thisJoinPoint.getSignature();
        final Method method = sig.getMethod();
        final Annotation[][] annotations = method.getParameterAnnotations();

        int i = 1;
        for (final Object obj : thisJoinPoint.getArgs()) {
            Nonnull a = null;
            for (Annotation annotation : annotations[i - 1]) {
                if (annotation instanceof Nonnull) {
                    a = (Nonnull) annotation;
                    break;
                }
            }

            if (obj == null && a != null && a.when() == When.ALWAYS) {
                throw new IllegalArgumentException(new StringBuilder("Argument ")
                        .append(i)
                        .append(" for @Nonnull parameter of ")
                        .append(toString(sig))
                        .append(" must not be null")
                        .toString()
                );
            }
            i++;
        }
    }

    private static StringBuilder toString(final MethodSignature sig) {
        final Method method = sig.getMethod();
        final Class[] args = method.getParameterTypes();
        final StringBuilder builder = new StringBuilder();
        builder.append('\'')
               .append(method.getReturnType().getSimpleName())
               .append(" ")
               .append(sig.getDeclaringType().getCanonicalName())
               .append('.')
               .append(method.getName())
               .append('(');
        boolean started = true;
        for (final Class arg : args) {
            if (!started) {
                builder.append(", ");
            } else {
                started = false;
            }
            builder.append(arg.getCanonicalName());
        }
        builder.append(")'");
        return builder;
    }
}


inspections

inspections

Signed-off-by: Ketoth Xupack <2ff7bd69a79a23dbf64ebd5846a612566f93fbf7@gmail.com>

package org.nohope.validation;

import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.aspectj.lang.reflect.ConstructorSignature;
import org.aspectj.lang.reflect.MethodSignature;

import javax.annotation.Nonnull;
import javax.annotation.meta.When;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final privileged aspect NotNullAspect {
    private static final Map<Constructor, MethodCache> constructorCache = new ConcurrentHashMap<>();
    private static final Map<Method, MethodCache> methodCache = new ConcurrentHashMap<>();

    /** Utility constructor. */
    private NotNullAspect() {
    }

    pointcut thisAdvice(): adviceexecution() && within(NotNullAspect);

    /**
     * matches all constructors with at last one parameter
     * marked with @Nonnull annotation
     */
    pointcut nonNullConstructorParameters():
            execution(new(.., @javax.annotation.Nonnull (*), ..))
            && !cflow(thisAdvice())
            ;

    /**
     * searches for all methods have at last one parameter
     * annotated with @Nonnull
     */
    pointcut nonNullMethodParameters():
            execution(* *.*(.., @javax.annotation.Nonnull (*), ..))
            && !cflow(thisAdvice())
            ;

    /**
     * searches for all methods which returns any reference type and
     * annotated with @Nonnull
     */
    static pointcut validatedReturnValue():
            execution(@javax.annotation.Nonnull (Object+) *.*(..))
            && !cflow(thisAdvice())
            ;

    @SuppressAjWarnings
    after() returning(final Object ret): validatedReturnValue() {
        final MethodSignature sig = (MethodSignature) thisJoinPoint.getStaticPart().getSignature();
        if (ret == null) {
            throw new IllegalStateException("@Nonnull method "
                    + toString(sig.getMethod())
                    + " must not return null");
        }
    }

    @SuppressAjWarnings
    before(): nonNullMethodParameters() || nonNullConstructorParameters() {
        final Signature signature = thisJoinPoint.getStaticPart().getSignature();
        final MethodCache cache;

        if (signature instanceof MethodSignature) {
            final MethodSignature sig = (MethodSignature) thisJoinPoint.getStaticPart().getSignature();
            final Method method = sig.getMethod();
            cache = getCached(method);
        } else if (signature instanceof ConstructorSignature) {
            final ConstructorSignature sig = (ConstructorSignature) signature;
            final Constructor method = sig.getConstructor();
            cache = getCached(method);
        } else {
            throw new IllegalStateException("Illegal advice for " + signature.getClass());
        }

        final Object[] args = thisJoinPoint.getArgs();
        final int constructorDiff = args.length - cache.params.length;
        for (int j = constructorDiff; j < args.length; j++) {
            final Object obj = args[j];
            Nonnull a = null;
            for (Annotation annotation : cache.params[j - constructorDiff]) {
                if (annotation instanceof Nonnull) {
                    a = (Nonnull) annotation;
                    break;
                }
            }

            if (obj == null && a != null && a.when() == When.ALWAYS) {
                throw new IllegalArgumentException("Argument "
                        + (j - constructorDiff + 1)
                        + " for @Nonnull parameter of "
                        + cache.message
                        + " must not be null"
                );
            }
        }
    }

    private static MethodCache getCached(final Method method) {
        MethodCache result = methodCache.get(method);
        if (result == null) {
            result = new MethodCache(NotNullAspect.toString(method),
                    method.getParameterAnnotations());
            methodCache.put(method, result);
        }
        return result;
    }

    private static MethodCache getCached(final Constructor constructor) {
        MethodCache result = constructorCache.get(constructor);
        if (result == null) {
            result = new MethodCache(NotNullAspect.toString(constructor),
                    constructor.getParameterAnnotations());
            constructorCache.put(constructor, result);
        }
        return result;
    }

    private static String toString(final Constructor method) {
        final Class[] args = method.getParameterTypes();
        String builder = '\''
                + method.getName()
                + '('
                ;
        boolean started = true;
        for (final Class arg : args) {
            if (!started) {
                builder += ", ";
            } else {
                started = false;
            }
            builder = arg.getCanonicalName();
        }
        builder = ")'";
        return builder;
    }

    private static String toString(final Method method) {
        final Class[] args = method.getParameterTypes();
        String builder = '\''
                + method.getReturnType().getSimpleName()
                +  " "
                + method.getDeclaringClass().getCanonicalName()
                + '.'
                + method.getName()
                + '('
                ;
        boolean started = true;
        for (final Class arg : args) {
            if (!started) {
                builder += ", ";
            } else {
                started = false;
            }
            builder += arg.getCanonicalName();
        }
        builder += ")'";
        return builder;
    }

    private static final class MethodCache {
        private final String message;
        private final Annotation[][] params;

        private MethodCache(final String message, final Annotation[][] params) {
            this.message = message;
            this.params = params;
        }
    }
}

package org.nohope.validation;

import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.aspectj.lang.reflect.ConstructorSignature;
import org.aspectj.lang.reflect.MethodSignature;

import javax.annotation.Nonnull;
import javax.annotation.meta.When;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final privileged aspect NotNullAspect {
    private static final Map<Constructor, MethodCache> constructorCache = new ConcurrentHashMap<>();
    private static final Map<Method, MethodCache> methodCache = new ConcurrentHashMap<>();

    /** Utility constructor. */
    private NotNullAspect() {
    }

    pointcut thisAdvice(): adviceexecution() && within(NotNullAspect);

    /**
     * matches all constructors with at last one parameter
     * marked with @Nonnull annotation
     */
    pointcut nonNullConstructorParameters():
            execution(new(.., @javax.annotation.Nonnull (*), ..))
            && !cflow(thisAdvice())
            ;

    /**
     * searches for all methods have at last one parameter
     * annotated with @Nonnull
     */
    pointcut nonNullMethodParameters():
            execution(* *.*(.., @javax.annotation.Nonnull (*), ..))
            && !cflow(thisAdvice())
            ;

    /**
     * searches for all methods which returns any reference type and
     * annotated with @Nonnull
     */
    static pointcut validatedReturnValue():
            execution(@javax.annotation.Nonnull (Object+) *.*(..))
            && !cflow(thisAdvice())
            ;

    @SuppressAjWarnings
    after() returning(final Object ret): validatedReturnValue() {
        final MethodSignature sig = (MethodSignature) thisJoinPoint.getStaticPart().getSignature();
        if (ret == null) {
            throw new IllegalStateException("@Nonnull method "
                    + toString(sig.getMethod())
                    + " must not return null");
        }
    }

    @SuppressAjWarnings
    before(): nonNullMethodParameters() || nonNullConstructorParameters() {
        final Signature signature = thisJoinPoint.getStaticPart().getSignature();
        final MethodCache cache;

        if (signature instanceof MethodSignature) {
            final MethodSignature sig = (MethodSignature) thisJoinPoint.getStaticPart().getSignature();
            final Method method = sig.getMethod();
            cache = getCached(method);
        } else if (signature instanceof ConstructorSignature) {
            final ConstructorSignature sig = (ConstructorSignature) signature;
            final Constructor method = sig.getConstructor();
            cache = getCached(method);
        } else {
            throw new IllegalStateException("Illegal advice for " + signature.getClass());
        }

        final Object[] args = thisJoinPoint.getArgs();
        final int constructorDiff = args.length - cache.params.length;
        for (int j = constructorDiff; j < args.length; j++) {
            final Object obj = args[j];
            Nonnull a = null;
            for (Annotation annotation : cache.params[j - constructorDiff]) {
                if (annotation instanceof Nonnull) {
                    a = (Nonnull) annotation;
                    break;
                }
            }

            if (obj == null && a != null && a.when() == When.ALWAYS) {
                throw new IllegalArgumentException("Argument "
                        + (j - constructorDiff + 1)
                        + " for @Nonnull parameter of "
                        + cache.message
                        + " must not be null"
                );
            }
        }
    }

    private static MethodCache getCached(final Method method) {
        MethodCache result = methodCache.get(method);
        if (result == null) {
            result = new MethodCache(NotNullAspect.toString(method),
                    method.getParameterAnnotations());
            methodCache.put(method, result);
        }
        return result;
    }

    private static MethodCache getCached(final Constructor constructor) {
        MethodCache result = constructorCache.get(constructor);
        if (result == null) {
            result = new MethodCache(NotNullAspect.toString(constructor),
                    constructor.getParameterAnnotations());
            constructorCache.put(constructor, result);
        }
        return result;
    }

    private static String toString(final Constructor method) {
        final Class[] args = method.getParameterTypes();
        String builder = '\''
                + method.getName()
                + '('
                ;
        boolean started = true;
        for (final Class arg : args) {
            if (!started) {
                builder += ", ";
            } else {
                started = false;
            }
            builder = arg.getCanonicalName();
        }
        builder = ")'";
        return builder;
    }

    private static String toString(final Method method) {
        final Class[] args = method.getParameterTypes();
        String builder = '\''
                + method.getReturnType().getSimpleName()
                +  " "
                + method.getDeclaringClass().getCanonicalName()
                + '.'
                + method.getName()
                + '('
                ;
        boolean started = true;
        for (final Class arg : args) {
            if (!started) {
                builder += ", ";
            } else {
                started = false;
            }
            builder += arg.getCanonicalName();
        }
        builder += ")'";
        return builder;
    }

    private static class MethodCache {
        private final String message;
        private final Annotation[][] params;

        private MethodCache(final String message, final Annotation[][] params) {
            this.message = message;
            this.params = params;
        }
    }
}


SPR-2199

SPR-2199

git-svn-id: b619a0c99665f88f1afe72824344cefe9a1c8c90@10875 fd5a2b45-1f63-4059-99e9-3c7cb7fd75c8

/*
 * Copyright 2002-2005 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.aspectj;

import java.lang.reflect.Method;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.interceptor.TransactionAttributeSource;

/**
 * Abstract superaspect for AspectJ transaction aspects. Concrete
 * subaspects will implement the transactionalMethodExecution()
 * pointcut using a strategy such as Java 5 annotations.
 *
 *
Suitable for use inside or outside the Spring IoC container.
 * Set the "transactionManager" property appropriately, allowing
 * use of any transaction implementation supported by Spring.
 *
 *
NB: If a method implements an interface that is itself
 * transactionally annotated, the relevant Spring transaction attribute
 * will not be resolved. This behavior will vary from that of Spring AOP
 * if proxying an interface (but not when proxying a class). We recommend that
 * transaction annotations should be added to classes, rather than business
 * interfaces, as they are an implementation detail rather than a contract
 * specification validation.
 *
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @since 2.0
 */
public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport {

	/**
	 * Construct object using the given transaction metadata retrieval strategy.
	 * @param tas TransactionAttributeSource implementation, retrieving Spring
	 * transaction metadata for each joinpoint. Write the subclass to pass in null
	 * if it's intended to be configured by Setter Injection.
	 */
	protected AbstractTransactionAspect(TransactionAttributeSource tas) {
		setTransactionAttributeSource(tas);
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	before(Object txObject) : transactionalMethodExecution(txObject) {
		MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
		Method method = methodSignature.getMethod();
		//  Create transaction if necessary.
		TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass());
		if (logger.isDebugEnabled()) {
			logger.debug("Aspect-created transaction: " + txInfo);
		}
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) {
    try {
      doCloseTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t);
    }
    catch (Throwable th) {
      logger.error("Failed to close transaction after throwing in a Transactional method", th);
    }
  }

	@SuppressAjWarnings("adviceDidNotMatch")
	after(Object txObject) returning() : transactionalMethodExecution(txObject) {
		doCommitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo());
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	after(Object txObject) : transactionalMethodExecution(txObject) {
		doFinally(TransactionAspectSupport.currentTransactionInfo());
	}

	// TODO extend TransactionAttributeSource to support join points besides methods

	/**
	 * Concrete subaspects must implement this pointcut, to identify
	 * transactional methods. For each selected joinpoint, TransactionMetadata
	 * will be retrieved using Spring's TransactionAttributeSource interface.
	 */
	protected abstract pointcut transactionalMethodExecution(Object txObject);

}

/*
 * Copyright 2002-2005 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.aspectj;

import java.lang.reflect.Method;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.interceptor.TransactionAttributeSource;

/**
 * Abstract superaspect for AspectJ transaction aspects. Concrete
 * subaspects will implement the transactionalMethodExecution()
 * pointcut using a strategy such as Java 5 annotations.
 *
 *
Suitable for use inside or outside the Spring IoC container.
 * Set the "transactionManager" property appropriately, allowing
 * use of any transaction implementation supported by Spring.
 *
 *
NB: If a method implements an interface that is itself
 * transactionally annotated, the relevant Spring transaction attribute
 * will not be resolved. This behavior will vary from that of Spring AOP
 * if proxying an interface (but not when proxying a class). We recommend that
 * transaction annotations should be added to classes, rather than business
 * interfaces, as they are an implementation detail rather than a contract
 * specification validation.
 *
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @since 2.0
 */
public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport {

	/**
	 * Construct object using the given transaction metadata retrieval strategy.
	 * @param tas TransactionAttributeSource implementation, retrieving Spring
	 * transaction metadata for each joinpoint. Write the subclass to pass in null
	 * if it's intended to be configured by Setter Injection.
	 */
	protected AbstractTransactionAspect(TransactionAttributeSource tas) {
		setTransactionAttributeSource(tas);
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	before(Object txObject) : transactionalMethodExecution(txObject) {
		MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
		Method method = methodSignature.getMethod();
		//  Create transaction if necessary.
		TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass());
		if (logger.isDebugEnabled()) {
			logger.debug("Aspect-created transaction: " + txInfo);
		}
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) {
		doCloseTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t);
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	after(Object txObject) returning() : transactionalMethodExecution(txObject) {
		doCommitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo());
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	after(Object txObject) : transactionalMethodExecution(txObject) {
		doFinally(TransactionAspectSupport.currentTransactionInfo());
	}

	// TODO extend TransactionAttributeSource to support join points besides methods

	/**
	 * Concrete subaspects must implement this pointcut, to identify
	 * transactional methods. For each selected joinpoint, TransactionMetadata
	 * will be retrieved using Spring's TransactionAttributeSource interface.
	 */
	protected abstract pointcut transactionalMethodExecution(Object txObject);

}


fix the bean initialization eror

fix the bean initialization eror

package org.slc.sli.aspect;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.CollectionOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.slc.sli.domain.Entity;
import org.slc.sli.domain.Repository;
import org.slc.sli.dal.repository.MongoRepository;

import org.slc.sli.common.util.logging.SecurityEvent;
import org.slc.sli.common.util.logging.LoggerCarrier;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

public aspect LoggerCarrierAspect {
	declare parents : (org.slc.sli.ingestion..* &&
            !java.lang.Enum+)  implements LoggerCarrier;

    private Repository<Entity> entityRepository;

//    private MongoTemplate template;

//    public MongoTemplate getTemplate() {
//    	return template;
//    }

//    public void setTemplate(MongoTemplate template) {
//    	this.template = template;
//    }

    @Value("${sli.ingestion.securityEvent.capSize}")
    private String capSize;

    public void LoggerCarrier.audit(SecurityEvent event) {
        MongoRepository<Entity> mer = (MongoRepository<Entity>) LoggerCarrierAspect.aspectOf().getEntityRepository();
        if (mer != null) {
            MongoTemplate mongoTemplate = mer.getTemplate();
            String capSizeStr = LoggerCarrierAspect.aspectOf().getCapSize();

            if (capSizeStr != null && !capSizeStr.isEmpty()) {
                int capSizeInt = Integer.parseInt(capSizeStr);
                // UN: If the collection is not present, create the capped collection.
                // However, if it is present and uncapped, change it to capped collection
                // 496 bytes is size of 1 security event document * capsize ~ the size that we want.
                if (!mongoTemplate.collectionExists("securityEvent")) {
                    CollectionOptions collectionOptions = new CollectionOptions(capSizeInt * 496, capSizeInt, true);
                    mongoTemplate.createCollection("securityEvent", collectionOptions);
                } else {
                    if (!mongoTemplate.getCollection("securityEvent").isCapped()) {
                        DBObject cmd = new BasicDBObject();
                        cmd.put("convertToCapped", "securityEvent");
                        cmd.put("size", capSizeInt * 496);
                        mongoTemplate.getDb().command(cmd);
                    }
                }
            }

            Map<String, Object> metadata = new HashMap<String, Object>();
            metadata.put("tenantId", event.getTenantId());
            mer.create("securityEvent", event.getProperties(), metadata, "securityEvent");
        } else {
            LoggerFactory.getLogger("SecurityMonitor").info("[Could not log SecurityEvent to mongo!]");
        }

        switch (event.getLogLevel()) {
            case TYPE_DEBUG:
                LoggerFactory.getLogger("SecurityMonitor").debug(event.toString());
                break;

            case TYPE_WARN:
                LoggerFactory.getLogger("SecurityMonitor").warn(event.toString());
                break;

            case TYPE_INFO:
                LoggerFactory.getLogger("SecurityMonitor").info(event.toString());
                break;

            case TYPE_ERROR:
                LoggerFactory.getLogger("SecurityMonitor").error(event.toString());
                break;

            case TYPE_TRACE:
                LoggerFactory.getLogger("SecurityMonitor").trace(event.toString());
                break;

            default:
                LoggerFactory.getLogger("SecurityMonitor").info(event.toString());
                break;
        }
    }

    public Repository<Entity> getEntityRepository() {
        return entityRepository;
    }

    public void setEntityRepository(Repository<Entity> entityRepository) {
        this.entityRepository = entityRepository;
    }

    public String getCapSize() {
        return capSize;
    }

    public void setCapSize(String capSize) {
        this.capSize = capSize;
    }

}

package org.slc.sli.aspect;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.CollectionOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.slc.sli.domain.Entity;
import org.slc.sli.domain.Repository;
import org.slc.sli.dal.repository.MongoRepository;

import org.slc.sli.common.util.logging.SecurityEvent;
import org.slc.sli.common.util.logging.LoggerCarrier;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

public aspect LoggerCarrierAspect {
	declare parents : (org.slc.sli.ingestion..* &&
            !java.lang.Enum+)  implements LoggerCarrier;

    private Repository<Entity> entityRepository;

    private MongoTemplate template;

    public MongoTemplate getTemplate() {
    	return template;
    }

    public void setTemplate(MongoTemplate template) {
    	this.template = template;
    }

    @Value("${sli.ingestion.securityEvent.capSize}")
    private String capSize;

    public void LoggerCarrier.audit(SecurityEvent event) {
        MongoRepository<Entity> mer = (MongoRepository<Entity>) LoggerCarrierAspect.aspectOf().getEntityRepository();
        if (mer != null) {
            MongoTemplate mongoTemplate = mer.getTemplate();
            String capSizeStr = LoggerCarrierAspect.aspectOf().getCapSize();

            if (capSizeStr != null && !capSizeStr.isEmpty()) {
                int capSizeInt = Integer.parseInt(capSizeStr);
                // UN: If the collection is not present, create the capped collection.
                // However, if it is present and uncapped, change it to capped collection
                // 496 bytes is size of 1 security event document * capsize ~ the size that we want.
                if (!mongoTemplate.collectionExists("securityEvent")) {
                    CollectionOptions collectionOptions = new CollectionOptions(capSizeInt * 496, capSizeInt, true);
                    mongoTemplate.createCollection("securityEvent", collectionOptions);
                } else {
                    if (!mongoTemplate.getCollection("securityEvent").isCapped()) {
                        DBObject cmd = new BasicDBObject();
                        cmd.put("convertToCapped", "securityEvent");
                        cmd.put("size", capSizeInt * 496);
                        mongoTemplate.getDb().command(cmd);
                    }
                }
            }

            Map<String, Object> metadata = new HashMap<String, Object>();
            metadata.put("tenantId", event.getTenantId());
            mer.create("securityEvent", event.getProperties(), metadata, "securityEvent");
        } else {
            LoggerFactory.getLogger("SecurityMonitor").info("[Could not log SecurityEvent to mongo!]");
        }

        switch (event.getLogLevel()) {
            case TYPE_DEBUG:
                LoggerFactory.getLogger("SecurityMonitor").debug(event.toString());
                break;

            case TYPE_WARN:
                LoggerFactory.getLogger("SecurityMonitor").warn(event.toString());
                break;

            case TYPE_INFO:
                LoggerFactory.getLogger("SecurityMonitor").info(event.toString());
                break;

            case TYPE_ERROR:
                LoggerFactory.getLogger("SecurityMonitor").error(event.toString());
                break;

            case TYPE_TRACE:
                LoggerFactory.getLogger("SecurityMonitor").trace(event.toString());
                break;

            default:
                LoggerFactory.getLogger("SecurityMonitor").info(event.toString());
                break;
        }
    }

    public Repository<Entity> getEntityRepository() {
        return entityRepository;
    }

    public void setEntityRepository(Repository<Entity> entityRepository) {
        this.entityRepository = entityRepository;
    }

    public String getCapSize() {
        return capSize;
    }

    public void setCapSize(String capSize) {
        this.capSize = capSize;
    }

}


Catch object registration exception when its done more than one time

package publichealthcomplaint.distribution.aspects;

import java.rmi.server.UnicastRemoteObject;

import javax.servlet.http.HttpServletRequest;

import publichealthcomplaint.datatypes.Constants;
import publichealthcomplaint.rmiconnector.HealthWatcherFacade;

public abstract aspect AAServerDistribution {

	public abstract pointcut registering();

	public abstract pointcut callRequest(HttpServletRequest request);

	before(): registering(){

		try {
			System.out.println("Creating RMI server...");

			String remoteObjectName = new String("//" + Constants.SERVER_NAME + "/"+ Constants.SYSTEM_NAME);
			boolean objectIsAlreadyBinded = false;

			String[] bindedList = java.rmi.Naming.list("//" + Constants.SERVER_NAME + "/"	+ Constants.SYSTEM_NAME);

			System.out.println("[AAServerDistribution:callRequest()] object "+ remoteObjectName +" is not bind yet");

			HealthWatcherFacade adapter = HealthWatcherFacade.getInstance();

			//begin debug
			if(adapter == null)
				System.out.println("[AAServerDistribution:registering()] adapter is null");
			else
				System.out.println("[AAServerDistribution:registering()] adapter = "+adapter);
			//end debug

			try
			{
				UnicastRemoteObject.exportObject(adapter);
			}
			catch (java.rmi.RemoteException rmiEx)
			{
				// object already exported
			}

			System.out.println("[AAServerDistribution:registering()]  Object "+ adapter.getClass().getName() +" exported");
			java.rmi.Naming.rebind("//" + Constants.SERVER_NAME + "/"
					+ Constants.SYSTEM_NAME, adapter);
			System.out.println("[AAServerDistribution:registering()]  Server created and ready.");

		}   catch (java.rmi.RemoteException rmiEx) {
			System.err.println("[AAServerDistribution:registering()] "+rmiEx.getLocalizedMessage());
			rmiEx.printStackTrace();
			rmiFacadeExceptionHandling(rmiEx);
		} catch (java.net.MalformedURLException rmiEx) {
			System.err.println("[AAServerDistribution:registering()] "+rmiEx.getLocalizedMessage());
			rmiEx.printStackTrace();
			rmiFacadeExceptionHandling(rmiEx);
		}
	}

	/**
	 * Compare the strings which represent the remote object in order to check if the object is already binded
	 * @param remoteObjectCandidate
	 * @param alreadyBindedObject
	 * @return
	 */
	private boolean isAlreadyBinded(String remoteObjectCandidate, String alreadyBindedObject){
		if( remoteObjectCandidate == null || alreadyBindedObject == null )
			return false;

		String canditateName = extractObjectName(remoteObjectCandidate);
		String objBinded = extractObjectName(alreadyBindedObject);

		System.out.println(canditateName+" == "+objBinded);
		if( canditateName.equals(objBinded))
			return true;
		else
			return false;

	}

	//get the name of the object that is the substring after the last '/'
	private String extractObjectName(String fullPath){
		if( ( fullPath != null) && ( fullPath.contains("/") ) ){
			String[] aux = fullPath.split("/");
			if( aux != null ){
				int length = aux.length;
				String nameBinded = aux[ length - 1 ];
				return nameBinded;
			}
		}
		return null;
	}

	private void rmiFacadeExceptionHandling(Throwable exception) {
		System.out.println("**************************************************");
		System.out.println("* Error during server initialization!            *");
		System.out.println("* The exception message is:                      *");
		System.out.println("      " + exception.getMessage()                   );
		System.out.println("* You may have to restart the server or registry.*");
		System.out.println("**************************************************");
		exception.printStackTrace();
	}
}

package publichealthcomplaint.distribution.aspects;

import java.rmi.server.UnicastRemoteObject;

import javax.servlet.http.HttpServletRequest;

import publichealthcomplaint.datatypes.Constants;
import publichealthcomplaint.rmiconnector.HealthWatcherFacade;

public abstract aspect AAServerDistribution {

	public abstract pointcut registering();

	public abstract pointcut callRequest(HttpServletRequest request);

	before(): registering(){

		try {
			System.out.println("Creating RMI server...");

			String remoteObjectName = new String("//" + Constants.SERVER_NAME + "/"+ Constants.SYSTEM_NAME);
			boolean objectIsAlreadyBinded = false;

			String[] bindedList = java.rmi.Naming.list("//" + Constants.SERVER_NAME + "/"	+ Constants.SYSTEM_NAME);

			System.out.println("[AAServerDistribution:callRequest()] object "+ remoteObjectName +" is not bind yet");

			HealthWatcherFacade adapter = HealthWatcherFacade.getInstance();

			//begin debug
			if(adapter == null)
				System.out.println("[AAServerDistribution:registering()] adapter is null");
			else
				System.out.println("[AAServerDistribution:registering()] adapter = "+adapter);
			//end debug

			UnicastRemoteObject.exportObject(adapter);
			System.out.println("[AAServerDistribution:registering()]  Object "+ adapter.getClass().getName() +" exported");
			java.rmi.Naming.rebind("//" + Constants.SERVER_NAME + "/"
					+ Constants.SYSTEM_NAME, adapter);
			System.out.println("[AAServerDistribution:registering()]  Server created and ready.");

		}   catch (java.rmi.RemoteException rmiEx) {
			System.err.println("[AAServerDistribution:registering()] "+rmiEx.getLocalizedMessage());
			rmiEx.printStackTrace();
			rmiFacadeExceptionHandling(rmiEx);
		} catch (java.net.MalformedURLException rmiEx) {
			System.err.println("[AAServerDistribution:registering()] "+rmiEx.getLocalizedMessage());
			rmiEx.printStackTrace();
			rmiFacadeExceptionHandling(rmiEx);
		}
	}

	/**
	 * Compare the strings which represent the remote object in order to check if the object is already binded
	 * @param remoteObjectCandidate
	 * @param alreadyBindedObject
	 * @return
	 */
	private boolean isAlreadyBinded(String remoteObjectCandidate, String alreadyBindedObject){
		if( remoteObjectCandidate == null || alreadyBindedObject == null )
			return false;

		String canditateName = extractObjectName(remoteObjectCandidate);
		String objBinded = extractObjectName(alreadyBindedObject);

		System.out.println(canditateName+" == "+objBinded);
		if( canditateName.equals(objBinded))
			return true;
		else
			return false;

	}

	//get the name of the object that is the substring after the last '/'
	private String extractObjectName(String fullPath){
		if( ( fullPath != null) && ( fullPath.contains("/") ) ){
			String[] aux = fullPath.split("/");
			if( aux != null ){
				int length = aux.length;
				String nameBinded = aux[ length - 1 ];
				return nameBinded;
			}
		}
		return null;
	}

	private void rmiFacadeExceptionHandling(Throwable exception) {
		System.out.println("**************************************************");
		System.out.println("* Error during server initialization!            *");
		System.out.println("* The exception message is:                      *");
		System.out.println("      " + exception.getMessage()                   );
		System.out.println("* You may have to restart the server or registry.*");
		System.out.println("**************************************************");
		exception.printStackTrace();
	}
}


Apply ListenableFuture support to AspectJ

Prior to this commit, only @Async annotated methods with proxy style
had an explicit support for ListenableFuture. This commit brings that
support to AspectJ as well.

Issue: SPR-12092

/*
 * Copyright 2002-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.scheduling.aspectj;

import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.aop.interceptor.AsyncExecutionAspectSupport;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;

/**
 * Abstract aspect that routes selected methods asynchronously.
 *
 * <p>This aspect needs to be injected with an implementation of
 * {@link Executor} to activate it for a specific thread pool.
 * Otherwise it will simply delegate all calls synchronously.
 *
 * @author Ramnivas Laddad
 * @author Juergen Hoeller
 * @author Chris Beams
 * @author Stephane Nicoll
 * @since 3.0.5
 */
public abstract aspect AbstractAsyncExecutionAspect extends AsyncExecutionAspectSupport {

	/**
	 * Create an {@code AnnotationAsyncExecutionAspect} with a {@code null} default
	 * executor, which should instead be set via {@code #aspectOf} and
	 * {@link #setExecutor(Executor)}. The same applies for {@link #setExceptionHandler}
	 */
	public AbstractAsyncExecutionAspect() {
		super(null);
	}

	/**
	 * Apply around advice to methods matching the {@link #asyncMethod()} pointcut,
	 * submit the actual calling of the method to the correct task executor and return
	 * immediately to the caller.
	 * @return {@link Future} if the original method returns {@code Future}; {@code null}
	 * otherwise.
	 */
	Object around() : asyncMethod() {
		final MethodSignature methodSignature = (MethodSignature) thisJoinPointStaticPart.getSignature();
		AsyncTaskExecutor executor = determineAsyncExecutor(methodSignature.getMethod());
		if (executor == null) {
			return proceed();
		}
		Callable<Object> callable = new Callable<Object>() {
			public Object call() throws Exception {
				try {
					Object result = proceed();
					if (result instanceof Future) {
						return ((Future<?>) result).get();
					}
				}
				catch (Throwable ex) {
					handleError(ex, methodSignature.getMethod(), thisJoinPoint.getArgs());
				}
				return null;
			}};

		Class<?> returnType = methodSignature.getReturnType();
		if (ListenableFuture.class.isAssignableFrom(returnType)) {
			return ((AsyncListenableTaskExecutor) executor).submitListenable(callable);
		}
		else if (Future.class.isAssignableFrom(returnType)) {
			return executor.submit(callable);
		}
		else {
			executor.submit(callable);
			return null;
		}
	}

	/**
	 * Return the set of joinpoints at which async advice should be applied.
	 */
	public abstract pointcut asyncMethod();

}

/*
 * Copyright 2002-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.scheduling.aspectj;

import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.aop.interceptor.AsyncExecutionAspectSupport;
import org.springframework.core.task.AsyncTaskExecutor;

/**
 * Abstract aspect that routes selected methods asynchronously.
 *
 * <p>This aspect needs to be injected with an implementation of
 * {@link Executor} to activate it for a specific thread pool.
 * Otherwise it will simply delegate all calls synchronously.
 *
 * @author Ramnivas Laddad
 * @author Juergen Hoeller
 * @author Chris Beams
 * @author Stephane Nicoll
 * @since 3.0.5
 */
public abstract aspect AbstractAsyncExecutionAspect extends AsyncExecutionAspectSupport {

	/**
	 * Create an {@code AnnotationAsyncExecutionAspect} with a {@code null} default
	 * executor, which should instead be set via {@code #aspectOf} and
	 * {@link #setExecutor(Executor)}. The same applies for {@link #setExceptionHandler}
	 */
	public AbstractAsyncExecutionAspect() {
		super(null);
	}

	/**
	 * Apply around advice to methods matching the {@link #asyncMethod()} pointcut,
	 * submit the actual calling of the method to the correct task executor and return
	 * immediately to the caller.
	 * @return {@link Future} if the original method returns {@code Future}; {@code null}
	 * otherwise.
	 */
	Object around() : asyncMethod() {
		final MethodSignature methodSignature = (MethodSignature) thisJoinPointStaticPart.getSignature();
		AsyncTaskExecutor executor = determineAsyncExecutor(methodSignature.getMethod());
		if (executor == null) {
			return proceed();
		}
		Callable<Object> callable = new Callable<Object>() {
			public Object call() throws Exception {
				try {
					Object result = proceed();
					if (result instanceof Future) {
						return ((Future<?>) result).get();
					}
				}
				catch (Throwable ex) {
					handleError(ex, methodSignature.getMethod(), thisJoinPoint.getArgs());
				}
				return null;
			}};
		Future<?> result = executor.submit(callable);
		if (Future.class.isAssignableFrom(methodSignature.getReturnType())) {
			return result;
		}
		else {
			return null;
		}
	}

	/**
	 * Return the set of joinpoints at which async advice should be applied.
	 */
	public abstract pointcut asyncMethod();

}


Fixed #2553.

Fixed #2553.

git-svn-id: f4ecfe233223879a4a16cd7937f11b5152963d8e@19496 5e8d7ff9-d8ef-0310-90f0-a4852d11357a

/*
 * Copyright 2005-2009 LAMP/EPFL
 */
// $Id$

package scala.tools.eclipse.contribution.weaving.jdt.core;

import java.util.Locale;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;

import scala.tools.eclipse.contribution.weaving.jdt.IScalaCompilationUnit;

@SuppressWarnings("restriction")
public privileged aspect DOMAspect {
  pointcut internalCreateAST(ASTParser parser, IProgressMonitor monitor) :
    execution(ASTNode ASTParser.internalCreateAST(IProgressMonitor)) &&
    args(monitor) &&
    target(parser);

  ASTNode around(ASTParser parser, IProgressMonitor monitor) :
    internalCreateAST(parser, monitor) {
    try {
      if (!(parser.typeRoot instanceof IScalaCompilationUnit))
        return proceed(parser, monitor);

      ICompilationUnit cu = (ICompilationUnit)parser.typeRoot;
      org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit)cu;

      IType[] topLevelTypes = cu.getTypes();
      int length = topLevelTypes.length;
      if (length == 0)
        throw new IllegalStateException();

      SourceTypeElementInfo[] topLevelInfos = new SourceTypeElementInfo[length];
      for (int i = 0; i < length; i++) {
        topLevelInfos[i] = (SourceTypeElementInfo) ((SourceType)topLevelTypes[i]).getElementInfo();
      }
      char[] fileName = ((ISourceType)topLevelInfos[0]).getFileName();

      CompilationResult result = new CompilationResult(fileName, 1, 1, 100);

      JavaProject javaProject = (JavaProject)cu.getJavaProject();
      Map compilerOptions0 = javaProject.getOptions(true);
      CompilerOptions compilerOptions = new CompilerOptions(compilerOptions0);
      compilerOptions.storeAnnotations = true;

      ProblemReporter problemReporter =
        new ProblemReporter(
          DefaultErrorHandlingPolicies.proceedWithAllProblems(),
          compilerOptions,
          new DefaultProblemFactory(Locale.getDefault()));

      int flags = SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE;

      CompilationUnitDeclaration unit =
        SourceTypeConverter.buildCompilationUnit(topLevelInfos, flags, problemReporter, result);

      INameEnvironment ne = javaProject.newSearchableNameEnvironment(DefaultWorkingCopyOwner.PRIMARY);
      final LookupEnvironment le = new LookupEnvironment(null, compilerOptions, problemReporter, ne);
      ITypeRequestor typeRequestor = new ITypeRequestor() {
        public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
          le.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
        }
        public void accept(org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit, AccessRestriction accessRestriction) {}
        public void accept(ISourceType[] sourceType, PackageBinding packageBinding, AccessRestriction accessRestriction) {}
      };
      le.typeRequestor = typeRequestor;

      le.buildTypeBindings(unit, null);
      le.completeTypeBindings();
      fixTypes(unit.types);

      AST ast = AST.newAST(AST.JLS3);
      ast.setFlag(AST.RESOLVED_BINDINGS);
      ast.setDefaultNodeFlag(ASTNode.ORIGINAL);

      org.eclipse.jdt.core.dom.ASTConverter converter =
        new org.eclipse.jdt.core.dom.ASTConverter(compilerOptions0, true, monitor);

      org.eclipse.jdt.core.dom.BindingResolver resolver =
        new org.eclipse.jdt.core.dom.DefaultBindingResolver(
          unit.scope,
          DefaultWorkingCopyOwner.PRIMARY,
          new org.eclipse.jdt.core.dom.DefaultBindingResolver.BindingTables(),
          true);
      ast.setBindingResolver(resolver);
      converter.setAST(ast);

      ASTNode node = converter.convert(unit, sourceUnit.getContents());
      return node;
    } catch (JavaModelException ex) {
      throw new IllegalArgumentException(ex);
    }
  }

  private void fixTypes(TypeDeclaration[] types) {
    for(int i = 0, iLimit = types.length; i < iLimit ; ++i) {
      TypeDeclaration tpe = types[i];
      tpe.binding.getAnnotationTagBits();
      tpe.scope.buildFields();
      tpe.scope.buildMethods();
      fixFields(tpe.fields);
      fixMethods(tpe.methods);
      fixTypes(tpe.memberTypes);
    }
  }

  private void fixMethods(AbstractMethodDeclaration[] methods) {
    if (methods == null)
      return;

    for(int i = 0, iLimit = methods.length; i < iLimit; ++i) {
      AbstractMethodDeclaration m = methods[i];
      m.bodyStart = m.declarationSourceStart;
      m.bodyEnd = m.declarationSourceEnd;
      m.binding.getAnnotationTagBits();
    }
  }

  private void fixFields(AbstractVariableDeclaration[] fields) {
    if (fields == null)
      return;

    for(int i = 0, iLimit = fields.length; i < iLimit; ++i) {
      AbstractVariableDeclaration f = fields[i];
      f.declarationEnd = f.declarationSourceEnd;
    }
  }
}

/*
 * Copyright 2005-2009 LAMP/EPFL
 */
// $Id$

package scala.tools.eclipse.contribution.weaving.jdt.core;

import java.util.Locale;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;

import scala.tools.eclipse.contribution.weaving.jdt.IScalaCompilationUnit;

@SuppressWarnings("restriction")
public privileged aspect DOMAspect {
  pointcut internalCreateAST(ASTParser parser, IProgressMonitor monitor) :
    execution(ASTNode ASTParser.internalCreateAST(IProgressMonitor)) &&
    args(monitor) &&
    target(parser);

  ASTNode around(ASTParser parser, IProgressMonitor monitor) :
    internalCreateAST(parser, monitor) {
    try {
      if (!(parser.typeRoot instanceof IScalaCompilationUnit))
        return proceed(parser, monitor);

      ICompilationUnit cu = (ICompilationUnit)parser.typeRoot;
      org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit)cu;

      IType[] topLevelTypes = cu.getTypes();
      int length = topLevelTypes.length;
      if (length == 0)
        throw new IllegalStateException();

      SourceTypeElementInfo[] topLevelInfos = new SourceTypeElementInfo[length];
      for (int i = 0; i < length; i++) {
        topLevelInfos[i] = (SourceTypeElementInfo) ((SourceType)topLevelTypes[i]).getElementInfo();
      }
      char[] fileName = ((ISourceType)topLevelInfos[0]).getFileName();

      CompilationResult result = new CompilationResult(fileName, 1, 1, 100);

      JavaProject javaProject = (JavaProject)cu.getJavaProject();
      Map compilerOptions0 = javaProject.getOptions(true);
      CompilerOptions compilerOptions = new CompilerOptions(compilerOptions0);
      compilerOptions.storeAnnotations = true;

      ProblemReporter problemReporter =
        new ProblemReporter(
          DefaultErrorHandlingPolicies.proceedWithAllProblems(),
          compilerOptions,
          new DefaultProblemFactory(Locale.getDefault()));

      int flags = SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE;

      CompilationUnitDeclaration unit =
        SourceTypeConverter.buildCompilationUnit(topLevelInfos, flags, problemReporter, result);

      INameEnvironment ne = javaProject.newSearchableNameEnvironment(DefaultWorkingCopyOwner.PRIMARY);
      final LookupEnvironment le = new LookupEnvironment(null, compilerOptions, problemReporter, ne);
      ITypeRequestor typeRequestor = new ITypeRequestor() {
        public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
          le.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
        }
        public void accept(org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit, AccessRestriction accessRestriction) {}
        public void accept(ISourceType[] sourceType, PackageBinding packageBinding, AccessRestriction accessRestriction) {}
      };
      le.typeRequestor = typeRequestor;

      le.buildTypeBindings(unit, null);
      le.completeTypeBindings();
      fixTypes(unit.types);

      AST ast = AST.newAST(AST.JLS3);
      ast.setFlag(AST.RESOLVED_BINDINGS);
      ast.setDefaultNodeFlag(ASTNode.ORIGINAL);

      org.eclipse.jdt.core.dom.ASTConverter converter =
        new org.eclipse.jdt.core.dom.ASTConverter(compilerOptions0, true, monitor);

      org.eclipse.jdt.core.dom.BindingResolver resolver =
        new org.eclipse.jdt.core.dom.DefaultBindingResolver(
          unit.scope,
          DefaultWorkingCopyOwner.PRIMARY,
          new org.eclipse.jdt.core.dom.DefaultBindingResolver.BindingTables(),
          true);
      ast.setBindingResolver(resolver);
      converter.setAST(ast);

      ASTNode node = converter.convert(unit, sourceUnit.getContents());
      return node;
    } catch (JavaModelException ex) {
      throw new IllegalArgumentException(ex);
    }
  }

  private void fixTypes(TypeDeclaration[] types) {
    for(int i = 0, iLimit = types.length; i < iLimit ; ++i) {
      TypeDeclaration tpe = types[i];
      tpe.binding.getAnnotationTagBits();
      tpe.scope.buildFields();
      tpe.scope.buildMethods();
      fixMethods(tpe, tpe.methods);
      fixTypes(tpe.memberTypes);
    }
  }

  private void fixMethods(TypeDeclaration tpe, AbstractMethodDeclaration[] methods) {
    for(int i = 0, iLimit = methods.length; i < iLimit; ++i) {
      AbstractMethodDeclaration m = methods[i];
      m.bodyStart = m.declarationSourceStart;
      m.bodyEnd = m.declarationSourceEnd;
      m.binding.getAnnotationTagBits();
    }
  }
}


BuildManagers weren't deleting invalidated classfiles; dependency tracker was only recording the dependency of Foo$.class on the source of object Foo ... Foo.class is now also recorded; the Eclipse Java builder could copy modified Scala sources to the output folder during incremental builds. Fixes #2428.

git-svn-id: f4ecfe233223879a4a16cd7937f11b5152963d8e@18920 5e8d7ff9-d8ef-0310-90f0-a4852d11357a

/*
 * Copyright 2005-2009 LAMP/EPFL
 */
// $Id$

package scala.tools.eclipse.contribution.weaving.jdt.builderoptions;

import org.eclipse.core.resources.IResource;

import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.internal.core.builder.BatchImageBuilder;
import org.eclipse.jdt.internal.core.builder.JavaBuilder;
//import org.eclipse.jdt.internal.core.builder.ClasspathMultiDirectory;
import org.eclipse.jdt.internal.core.util.Util;

@SuppressWarnings("restriction")
public privileged aspect ScalaJavaBuilderAspect {
  pointcut build() :
    execution(IProject[] ScalaJavaBuilder.build(int, Map, IProgressMonitor) throws CoreException);

  pointcut cleanOutputFolders(boolean copyBack) :
    args(copyBack) &&
    execution(void BatchImageBuilder.cleanOutputFolders(boolean) throws CoreException);

  pointcut isJavaLikeFileName(String fileName) :
    args(fileName) &&
    execution(boolean Util.isJavaLikeFileName(String));

  pointcut filterExtraResource(IResource resource) :
    args(resource) &&
    execution(boolean JavaBuilder.filterExtraResource(IResource));

  void around(BatchImageBuilder builder, boolean copyBack) throws CoreException :
    target(builder) &&
    cleanOutputFolders(copyBack) &&
    cflow(build()) {
    // Suppress the cleaning behaviour but do the extra resource copying if requested
    if (copyBack)
      for (int i = 0, l = builder.sourceLocations.length; i < l; i++) {
        org.eclipse.jdt.internal.core.builder.ClasspathMultiDirectory sourceLocation = builder.sourceLocations[i];
        if (sourceLocation.hasIndependentOutputFolder)
          builder.copyExtraResourcesBack(sourceLocation, false);
      }
  }

  boolean around(String fileName) :
    isJavaLikeFileName(fileName) &&
    cflow(build()) &&
    !cflow(cleanOutputFolders(*)) {
    if (fileName != null && fileName.endsWith("scala"))
      return false;
    else
      return proceed(fileName);
  }

  boolean around(IResource resource) :
    filterExtraResource(resource) &&
    cflow(build()) {
    return resource.getName().endsWith(".scala") || proceed(resource);
  }
}

/*
 * Copyright 2005-2009 LAMP/EPFL
 */
// $Id$

package scala.tools.eclipse.contribution.weaving.jdt.builderoptions;

import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.internal.core.builder.BatchImageBuilder;
//import org.eclipse.jdt.internal.core.builder.ClasspathMultiDirectory;
import org.eclipse.jdt.internal.core.util.Util;

@SuppressWarnings("restriction")
public privileged aspect ScalaJavaBuilderAspect {
  pointcut build() :
    execution(IProject[] ScalaJavaBuilder.build(int, Map, IProgressMonitor) throws CoreException);

  pointcut cleanOutputFolders(boolean copyBack) :
    args(copyBack) &&
    execution(void BatchImageBuilder.cleanOutputFolders(boolean) throws CoreException);

  pointcut isJavaLikeFileName(String fileName) :
    args(fileName) &&
    execution(boolean Util.isJavaLikeFileName(String));

  void around(BatchImageBuilder builder, boolean copyBack) throws CoreException :
    target(builder) &&
    cleanOutputFolders(copyBack) &&
    cflow(build()) {
    // Suppress the cleaning behaviour but do the extra resource copying if requested
    if (copyBack)
      for (int i = 0, l = builder.sourceLocations.length; i < l; i++) {
        org.eclipse.jdt.internal.core.builder.ClasspathMultiDirectory sourceLocation = builder.sourceLocations[i];
        if (sourceLocation.hasIndependentOutputFolder)
          builder.copyExtraResourcesBack(sourceLocation, false);
      }
  }

  boolean around(String fileName) :
    isJavaLikeFileName(fileName) &&
    cflow(build()) &&
    !cflow(cleanOutputFolders(*)) {
    if (fileName != null && fileName.endsWith("scala"))
      return false;
    else
      return proceed(fileName);
  }
}