All Downloads are FREE. Search and download functionalities are using the official Maven repository.

play.PlayPlugin Maven / Gradle / Ivy

package play;

import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.google.gson.JsonObject;

import play.classloading.ApplicationClasses.ApplicationClass;
import play.data.binding.RootParamNode;
import play.db.Model;
import play.libs.F;
import play.mvc.Http.Request;
import play.mvc.Http.Response;
import play.mvc.Router.Route;
import play.mvc.results.Result;
import play.templates.BaseTemplate;
import play.templates.Template;
import play.test.BaseTest;
import play.test.TestEngine.TestResults;
import play.vfs.VirtualFile;

/**
 * A framework plugin
 */
public abstract class PlayPlugin implements Comparable {

    /**
     * Plugin priority (0 for highest priority)
     */
    public int index;

    /**
     * Called at plugin loading
     */
    public void onLoad() {
    }

    public boolean compileSources() {
        return false;
    }

    /**
     * Run a test class
     * 
     * @param clazz
     *            the class to run
     * @return : tests results
     */
    public TestResults runTest(Class clazz) {
        return null;
    }

    /**
     * Use method using RootParamNode instead
     * 
     * @param name
     *            the name of the object
     * @param clazz
     *            the class of the object to bind
     * @param type
     *            type
     * @param annotations
     *            annotation on the object
     * @param params
     *            parameters to bind
     * @return binding object
     * 
     * @deprecated use {@link #bind(RootParamNode, String, Class, Type, Annotation[])}
     */
    @Deprecated
    public Object bind(String name, Class clazz, Type type, Annotation[] annotations, Map params) {
        return null;
    }

    /**
     * Called when play need to bind a Java object from HTTP params.
     *
     * When overriding this method, do not call super impl.. super impl is calling old bind method to be backward
     * compatible.
     * 
     * @param rootParamNode
     *            parameters to bind
     * @param name
     *            the name of the object
     * @param clazz
     *            the class of the object to bind
     * @param type
     *            type
     * @param annotations
     *            annotation on the object
     * @return binding object
     */
    public Object bind(RootParamNode rootParamNode, String name, Class clazz, Type type, Annotation[] annotations) {
        // call old method to be backward compatible
        return bind(name, clazz, type, annotations, rootParamNode.originalParams);
    }

    /**
     * @deprecated Use bindBean instead
     * @param name
     *            the name of the object
     * @param o
     *            object to bind
     * @param params
     *            parameters to bind
     * @return binding object
     */
    @Deprecated
    public Object bind(String name, Object o, Map params) {
        return null;
    }

    /**
     * Called when play need to bind an existing Java object from HTTP params. When overriding this method, DO NOT call
     * the super method, since its default impl is to call the old bind method to be backward compatible.
     * 
     * @param rootParamNode
     *            parameters to bind
     * @param name
     *            the name of the object
     * @param bean
     *            object to bind
     * @return binding object
     */
    public Object bindBean(RootParamNode rootParamNode, String name, Object bean) {
        // call old method to be backward compatible.
        return bind(name, bean, rootParamNode.originalParams);
    }

    /**
     * Unbind an object
     * 
     * @param src
     *            object to unbind
     * @param name
     *            the name of the object
     * @return List of parameters
     */
    public Map unBind(Object src, String name) {
        return null;
    }

    /**
     * Translate the given key for the given locale and arguments. If null is returned, Play's normal message
     * translation mechanism will be used.
     * 
     * @param locale
     *            the locale we want
     * @param key
     *            the message key
     * @param args
     *            arguments of the messages
     * @return the formatted string
     */
    public String getMessage(String locale, Object key, Object... args) {
        return null;
    }

    /**
     * Return the plugin status
     * 
     * @return the plugin status
     */
    public String getStatus() {
        return null;
    }

    /**
     * Return the plugin status in JSON format
     * 
     * @return the plugin status in JSON format
     */
    public JsonObject getJsonStatus() {
        return null;
    }

    /**
     * Enhance this class
     * 
     * @param applicationClass
     *            the class to enhance
     * @throws java.lang.Exception
     *             if cannot enhance the class
     */
    public void enhance(ApplicationClass applicationClass) throws Exception {
    }

    /**
     * This hook is not plugged, don't implement it
     * 
     * @param template
     *            the template to compile
     * @deprecated
     */
    @Deprecated
    public void onTemplateCompilation(Template template) {
    }

    /**
     * Give a chance to this plugin to fully manage this request
     * 
     * @param request
     *            The Play request
     * @param response
     *            The Play response
     * @return true if this plugin has managed this request
     * @throws java.lang.Exception
     *             if cannot enhance the class
     */
    public boolean rawInvocation(Request request, Response response) throws Exception {
        return false;
    }

    /**
     * Let a chance to this plugin to manage a static resource
     * 
     * @param file
     *            The requested file
     * @param request
     *            The Play request
     * @param response
     *            The Play response
     * @return true if this plugin has managed this request
     */
    public boolean serveStatic(VirtualFile file, Request request, Response response) {
        return false;
    }

    public void beforeDetectingChanges() {
    }

    /**
     * @param file
     *            the file of the template to load
     * @return the template object
     */
    public Template loadTemplate(VirtualFile file) {
        return null;
    }

    /**
     * It's time for the plugin to detect changes. Throw an exception is the application must be reloaded.
     */
    public void detectChange() {
    }

    /**
     * It's time for the plugin to detect changes. Throw an exception is the application must be reloaded.
     * 
     * @return false si no change detected
     */
    public boolean detectClassesChange() {
        return false;
    }

    /**
     * Called at application start (and at each reloading) Time to start stateful things.
     */
    public void onApplicationStart() {
    }

    /**
     * Called after the application start.
     */
    public void afterApplicationStart() {
    }

    /**
     * Called at application stop (and before each reloading) Time to shutdown stateful things.
     */
    public void onApplicationStop() {
    }

    /**
     * Called before a Play! invocation. Time to prepare request specific things.
     */
    public void beforeInvocation() {
    }

    /**
     * Called after an invocation. (unless an exception has been thrown). Time to close request specific things.
     */
    public void afterInvocation() {
    }

    /**
     * Called if an exception occurred during the invocation.
     * 
     * @param e
     *            The caught exception.
     */
    public void onInvocationException(Throwable e) {
    }

    /**
     * Called at the end of the invocation. (even if an exception occurred). Time to close request specific things.
     */
    public void invocationFinally() {
    }

    /**
     * Called before an 'action' invocation, ie an HTTP request processing.
     * 
     * @param actionMethod
     *            name of the method
     */
    public void beforeActionInvocation(Method actionMethod) {
    }

    /**
     * Called when the action method has thrown a result.
     * 
     * @param result
     *            The result object for the request.
     */
    public void onActionInvocationResult(Result result) {
    }

    public void onInvocationSuccess() {
    }

    /**
     * Called when the request has been routed.
     * 
     * @param route
     *            The route selected.
     */
    public void onRequestRouting(Route route) {
    }

    /**
     * Called at the end of the action invocation.
     */
    public void afterActionInvocation() {
    }

    /**
     * Called at the end of the action invocation (either in case of success or any failure).
     */
    public void onActionInvocationFinally() {
    }

    /**
     * Called when the application.conf has been read.
     */
    public void onConfigurationRead() {
    }

    /**
     * Called after routes loading.
     */
    public void onRoutesLoaded() {
    }

    /**
     * Event may be sent by plugins or other components
     * 
     * @param message
     *            convention: pluginClassShortName.message
     * @param context
     *            depends on the plugin
     */
    public void onEvent(String message, Object context) {
    }

    /**
     * @param modified
     *            list of modified class
     * @return List of class
     */
    public List onClassesChange(List modified) {
        return emptyList();
    }

    /**
     * @return List of the template extension
     */
    public List addTemplateExtensions() {
        return emptyList();
    }

    /**
     * Override to provide additional mime types from your plugin. These mimetypes get priority over the default
     * framework mimetypes but not over the application's configuration.
     * 
     * @return a Map from extensions (without dot) to mimetypes
     */
    public Map addMimeTypes() {
        return emptyMap();
    }

    /**
     * Let a chance to the plugin to compile it owns classes. Must be added to the mutable list.
     * 
     * @param classes
     *            list of class to compile
     * @deprecated
     */
    @Deprecated
    public void compileAll(List classes) {
    }

    /**
     * Let some plugins route themself
     * 
     * @param request
     *            the current request
     */
    public void routeRequest(Request request) {
    }

    /**
     * @param modelClass
     *            class of the model
     * @return the Model factory
     */
    public Model.Factory modelFactory(Class modelClass) {
        return null;
    }

    public void afterFixtureLoad() {
    }

    /**
     * Inter-plugin communication.
     * 
     * @param message
     *            the message to post
     * @param context
     *            an object
     */
    public static void postEvent(String message, Object context) {
        Play.pluginCollection.onEvent(message, context);
    }

    public void onApplicationReady() {
    }

    @Override
    public int compareTo(PlayPlugin o) {
        int res = index < o.index ? -1 : (index == o.index ? 0 : 1);
        if (res != 0) {
            return res;
        }

        // index is equal in both plugins.
        // Sort on class type to get consistent order
        res = this.getClass().getName().compareTo(o.getClass().getName());
        if (res != 0) {
            // classnames where different
            return res;
        }

        // Identical classnames.
        // Sort on instance to get consistent order.
        // We only return 0 (equal) if both identityHashCode are identical
        // which is only the case if both this and other are the same object instance.
        // This is consistent with equals() when no special equals-method is implemented.
        int thisHashCode = System.identityHashCode(this);
        int otherHashCode = System.identityHashCode(o);
        return (thisHashCode < otherHashCode ? -1 : (thisHashCode == otherHashCode ? 0 : 1));
    }

    public String overrideTemplateSource(BaseTemplate template, String source) {
        return null;
    }

    public Object willBeValidated(Object value) {
        return null;
    }

    /**
     * Implement to add some classes that should be considered unit tests but do not extend {@link org.junit.Assert} to
     * tests that can be executed by test runner (will be visible in test UI).
     * 

* Note:You probably will also need to override {@link PlayPlugin#runTest(java.lang.Class)} method * to handle unsupported tests execution properly. *

* Keep in mind that this method can only add tests to currently loaded ones. You cannot disable tests this way. You * should also make sure you do not duplicate already loaded tests. * * @return list of plugin supported unit test classes (empty list in default implementation) */ public Collection getUnitTests() { return emptyList(); } /** * Implement to add some classes that should be considered functional tests but do not extend * {@link play.test.FunctionalTest} to tests that can be executed by test runner (will be visible in test UI). *

* Note:You probably will also need to override {@link PlayPlugin#runTest(java.lang.Class)} method * to handle unsupported tests execution properly. *

* Keep in mind that this method can only add tests to currently loaded ones. You cannot disable tests this way. You * should also make sure you do not duplicate already loaded tests. * * @return list of plugin supported functional test classes (empty list in default implementation) */ public Collection getFunctionalTests() { return emptyList(); } /** * Class that define a filter. A filter is a class that wrap a certain behavior around an action. You can access * your Request and Response object within the filter. See the JPA plugin for an example. The JPA plugin wraps a * transaction around an action. The filter applies a transaction to the current Action. */ public abstract static class Filter { String name; public Filter(String name) { this.name = name; } public abstract T withinFilter(play.libs.F.Function0 fct) throws Throwable; /** * Surround innerFilter with this. (innerFilter after this) * * @param innerFilter * filter to be wrapped. * @return a new Filter object. newFilter.withinFilter(x) is * outerFilter.withinFilter(innerFilter.withinFilter(x)) */ public Filter decorate(final Filter innerFilter) { final Filter outerFilter = this; return new Filter(this.name) { @Override public T withinFilter(F.Function0 fct) throws Throwable { return compose(outerFilter.asFunction(), innerFilter.asFunction()).apply(fct); } }; } /** * Compose two second order functions whose input is a zero param function that returns type T... * * @param outer * Function that will wrap inner -- ("outer after inner") * @param inner * Function to be wrapped by outer function -- ("outer after inner") * @return A function that computes outer(inner(x)) on application. */ private static Function1, T> compose(final Function1, T> outer, final Function1, T> inner) { return new Function1, T>() { @Override public T apply(final F.Function0 arg) throws Throwable { return outer.apply(new F.Function0() { @Override public T apply() throws Throwable { return inner.apply(arg); } }); } }; } private final Function1, T> _asFunction = new Function1, T>() { @Override public T apply(F.Function0 arg) throws Throwable { return withinFilter(arg); } }; public Function1, T> asFunction() { return _asFunction; } public String getName() { return name; } // I don't want to add any additional dependencies to the project or use JDK 8 features // so I'm just rolling my own 1 arg function interface... there must be a better way to do this... public static interface Function1 { public O apply(I arg) throws Throwable; } } public final boolean hasFilter() { return this.getFilter() != null; } /** * Return the filter implementation for this plugin. * * @return filter object of this plugin */ public Filter getFilter() { return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy