Package dk.brics.jwig.analysis.jaive

Source Code of dk.brics.jwig.analysis.jaive.Interface

package dk.brics.jwig.analysis.jaive;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import dk.brics.automaton.Automaton;
import dk.brics.jwig.URLPattern;
import dk.brics.jwig.WebApp;
import dk.brics.jwig.WebSite;
import dk.brics.jwig.analysis.JwigResolver;
import dk.brics.jwig.server.RegisteredMethod;
import dk.brics.jwig.server.RequestManager;

/**
* The interface for a {@link WebSite}, containing all WebMethods and their
* containing {@link WebApp} .
*/
public class Interface {

    private final Map<Class<? extends WebApp>, RequestManager> managers;

    /**
     * Map from both classes and methods to the corresponding url pattern
     * automaton. Only used for caching.
     */
    private final IdentityHashMap<Object, Automaton> urlPatternAutomatons;

    /**
     * Constructs a new {@link Interface} for the given {@link WebApp}s and
     * WebMethods. Uses a {@link JwigResolver}.
     *
     * @param managers
     *            as the relation between {@link WebApp}s and WebMethods
     * @param resolver
     *            as the {@link JwigResolver}to use
     */
    public Interface(Map<Class<? extends WebApp>, RequestManager> managers) {
        this.managers = managers;
        this.urlPatternAutomatons = new IdentityHashMap<Object, Automaton>();
    }

    /**
     * concatenates two {@link Automaton}, with a slash in between.
     *
     * the accepted language of the new automaton is: "l(prefix)/l(suffix)"
     *
     * @param prefix
     *            as the prefix {@link Automaton}
     * @param suffix
     *            as the suffix {@link Automaton}
     * @return the concatenated {@link Automaton}
     */
    private Automaton concatenateWithSlash(Automaton prefix, Automaton suffix) {
        return prefix.concatenate(Automaton.makeChar('/')).concatenate(suffix);
    }

    /**
     * Finds the {@link Automaton} for a {@link URLPattern} of a {@link WebApp}.
     *
     * @param webAppClass
     *            as the {@link WebApp} to analyze
     * @return the {@link Automaton} representing the {@link URLPattern} of the
     *         {@link WebApp}
     */
    private Automaton constructURLPatternAutomaton(
            Class<? extends WebApp> webAppClass) {
        URLPattern urlPattern = webAppClass.getAnnotation(URLPattern.class);
        String pattern;
        if (urlPattern != null)
            pattern = urlPattern.value();
        else
            /**
             * the same default as
             * {@link RequestManager#introspectWebAppClass(Class)}.
             */
            pattern = webAppClass.getCanonicalName().replace('.', '/');

        return new URLPatternToAutomatonConverter().convert(pattern);
    }

    /**
     * Finds the {@link Automaton} for a {@link URLPattern} of a WebMethod.
     *
     * @param method
     *            as the WebMethod to analyze
     * @return the {@link Automaton} representing the {@link URLPattern} of the
     *         WebMethod
     */
    private Automaton constructURLPatternAutomaton(Method method) {
        URLPattern urlPattern = method.getAnnotation(URLPattern.class);
        String pattern;
        if (urlPattern != null)
            pattern = urlPattern.value();
        else
            pattern = method.getName();
        final Automaton converted = new URLPatternToAutomatonConverter()
                .convert(pattern);

        return converted;
    }

    /**
     * Caching method for finding the {@link Automaton} for a {@link URLPattern}
     * of a {@link WebApp}.
     *
     * @param webAppClass
     *            as the {@link WebApp} to analyze
     * @return the {@link Automaton} representing the {@link URLPattern} of the
     *         {@link WebApp}
     */
    private Automaton getURLPatternAutomaton(Class<? extends WebApp> webAppClass) {
        Automaton automaton = urlPatternAutomatons.get(webAppClass);
        if (automaton == null) {
            automaton = constructURLPatternAutomaton(webAppClass);
            urlPatternAutomatons.put(webAppClass, automaton);
        }
        return automaton;
    }

    /**
     * Caching method for finding the {@link Automaton} for a {@link URLPattern}
     * of a WebMethod.
     *
     * @param method
     *            as the WebMethod to analyze
     * @return the {@link Automaton} representing the {@link URLPattern} of the
     *         WebMethod
     */
    private Automaton getURLPatternAutomaton(Method method) {
        Automaton automaton = urlPatternAutomatons.get(method);
        if (automaton == null) {
            automaton = constructURLPatternAutomaton(method);
            urlPatternAutomatons.put(method, automaton);
        }
        return automaton;
    }

    /**
     * @return the {@link WebApp}s for the Interface.
     */
    public Set<Class<? extends WebApp>> getWebApps() {
        Set<Class<? extends WebApp>> apps = new HashSet<Class<? extends WebApp>>();
        for (Class<? extends WebApp> webApp : managers.keySet()) {
            apps.add(webApp);
        }
        return apps;

    }

    /**
     * Constructs the {@link FilterGroup} corresponding to the URL of the
     * WebMethod in a {@link WebApp}.
     *
     * @param webMethod
     *            as the WebMethod to extract an URL from.
     * @return the corresponding {@link FilterGroup}
     */
    public FilterGroup getFilterGroup(Method webMethod) {
        Set<Method> urlPatternMatches = new HashSet<Method>();
        @SuppressWarnings("unchecked")
        Automaton prefixedURLPattern = concatenateWithSlash(
                getURLPatternAutomaton((Class<? extends WebApp>) webMethod
                        .getDeclaringClass()),
                getURLPatternAutomaton(webMethod));
        // for each webmethod in the webapps, check if it could be hit by the
        // possible url patterns
        for (Entry<Class<? extends WebApp>, RequestManager> entry : managers
                .entrySet()) {
            for (RegisteredMethod registeredMethod : entry.getValue()
                    .getWebMethods()) {
                final Method possibleTargetedMethod = registeredMethod
                        .getMethod();
                if (!webMethod.equals(possibleTargetedMethod)) {
                    Automaton prefixedPossibleTarget = concatenateWithSlash(
                            getURLPatternAutomaton(entry.getKey()),
                            getURLPatternAutomaton(possibleTargetedMethod));
                    final boolean intersects = !prefixedURLPattern
                            .intersection(prefixedPossibleTarget).isEmpty();
                    if (intersects)
                        urlPatternMatches.add(possibleTargetedMethod);
                }
            }
        }
        return new FilterGroup(webMethod, urlPatternMatches);
    }

    /**
     * @return all WebMethods in the {@link WebSite}
     */
    public Set<RegisteredMethod> getRegisteredMethods() {
        Set<RegisteredMethod> methods = new HashSet<RegisteredMethod>();
        for (RequestManager manager : managers.values()) {
            methods.addAll(manager.getWebMethods());
        }
        return methods;
    }

    /**
     * Finds all WebMethods and Filters in the {@link WebApp} with names in the
     * language of the supplied automaton.
     *
     * @param webApp
     *            as the {@link WebApp} to find the WebMethods in
     * @param the
     *            {@link Automaton} to match with
     * @return the WebMethods of the {@link WebApp} whose names are matched by
     *         the {@link Automaton}
     */
    public Set<Method> getWebMethodsByName(Class<? extends WebApp> webAppClass,
            Automaton automaton) {
        final RequestManager manager = managers.get(webAppClass);
        if (manager == null)
            throw new IllegalArgumentException("WebApp: "
                    + webAppClass.getName() + " has not been registered");

        HashSet<Method> methodNameMatches = new HashSet<Method>();
        final List<RegisteredMethod> localWebMethods = manager.getWebMethods();
        for (RegisteredMethod methodNameMatch : localWebMethods) {
            final Method method = methodNameMatch.getMethod();
            if (automaton.run(method.getName())) {
                methodNameMatches.add(method);
            }
        }
        return methodNameMatches;
    }
}
TOP

Related Classes of dk.brics.jwig.analysis.jaive.Interface

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.