Package com.britesnow.snow.web.handler

Source Code of com.britesnow.snow.web.handler.WebObjectRegistry

package com.britesnow.snow.web.handler;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

import com.britesnow.snow.web.HttpMethod;
import com.britesnow.snow.web.binding.WebClasses;
import com.britesnow.snow.web.exception.WebExceptionCatcherRef;
import com.britesnow.snow.web.exception.annotation.WebExceptionCatcher;
import com.britesnow.snow.web.handler.annotation.FreemarkerMethodHandler;
import com.britesnow.snow.web.handler.annotation.WebActionHandler;
import com.britesnow.snow.web.handler.annotation.WebModelHandler;
import com.britesnow.snow.web.handler.annotation.WebResourceHandler;
import com.britesnow.snow.web.handler.annotation.FreemarkerDirectiveHandler;
import com.britesnow.snow.web.hook.HookRegistry;
import com.britesnow.snow.web.hook.annotation.WebApplicationHook;
import com.britesnow.snow.web.hook.annotation.WebRequestHook;
import com.britesnow.snow.web.param.resolver.WebParamResolverRegistry;
import com.britesnow.snow.web.renderer.freemarker.FreemarkerDirectiveProxy;
import com.britesnow.snow.web.renderer.freemarker.FreemarkerMethodProxy;
import com.britesnow.snow.web.rest.DefaultWebSerializers;
import com.britesnow.snow.web.rest.RestRegistry;
import com.britesnow.snow.web.rest.SerializerRegistry;
import com.britesnow.snow.web.rest.annotation.WebDelete;
import com.britesnow.snow.web.rest.annotation.WebGet;
import com.britesnow.snow.web.rest.annotation.WebPost;
import com.britesnow.snow.web.rest.annotation.WebPut;
import com.britesnow.snow.web.rest.annotation.WebSerializer;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;

@Singleton
public class WebObjectRegistry {

    private String[]                                                leafPaths;

    private Map<String, WebModelHandlerRef>                         webModelHandlerByStartsWithMap = new HashMap<String, WebModelHandlerRef>();
    private List<WebModelHandlerRef>                                webModelHandlerRefList         = new ArrayList<WebModelHandlerRef>();
    private Map<String, WebActionHandlerRef>                        webActionHandlerDic            = new HashMap<String, WebActionHandlerRef>();
    private List<WebResourceHandlerRef>                             webResourceHandlerList         = new ArrayList<WebResourceHandlerRef>();
    private List<FreemarkerDirectiveProxy>                          freemarkerDirectiveProxyList   = new ArrayList<FreemarkerDirectiveProxy>();
    private List<FreemarkerMethodProxy>                             freemarkerMethodProxyList      = new ArrayList<FreemarkerMethodProxy>();
    private Map<Class<? extends Throwable>, WebExceptionCatcherRef> webExceptionCatcherMap         = new HashMap<Class<? extends Throwable>, WebExceptionCatcherRef>();

    @Inject
    private WebParamResolverRegistry                                webParamResolverRegistry;

    @Inject
    private HookRegistry                                            hookRegistry;
   
    @Inject
    private RestRegistry                                            restRegistry;
   
    @Inject
    private SerializerRegistry                                      serializerRegistry;

    @Inject
    private ParamDefBuilder                                         paramDefBuilder;

    @Inject(optional = true)
    @Nullable
    @WebClasses
    private Class[]                                                webClasses;
   
    @Inject
    private Injector injector;

    /**
     * Must be called before calling registerWebHandlers.<br />
     * Must be called before at application init time (not thread safe). <br />
     */
    public void init() {
        webParamResolverRegistry.init();

        WebObjectValidationExceptions exs = new WebObjectValidationExceptions();
       
        // register the default
        registerWebObjectMethods(DefaultWebSerializers.class);

        if (webClasses != null) {
            for (Class webClass : webClasses) {
                try {
                    validateWebObject(webClass);
                    registerWebObjectMethods(webClass);
                } catch (WebObjectValidationException ex) {
                    exs.addWebException(ex);
                }
            }
        }
        if (exs.hasExceptions()) {
            throw exs;
        }
    }

    /**
     * Validate that the
     *
     * @param webObject
     * @since 2.0.0
     */
    private void validateWebObject(Class webClass) throws WebObjectValidationException {
        Class cls = webClass;

        Object an = cls.getAnnotation(Singleton.class);
        if (an == null) {
            an = cls.getAnnotation(javax.inject.Singleton.class);
        }
        if (an == null) {
            WebObjectValidationException ex = new WebObjectValidationException(cls, WebObjectValidationException.ERROR.NO_SINGLETON);
            throw ex;
        }
    }

    /**
     * Get the leafPaths (probably
     *
     * @return
     */
    public String[] getLeafPaths() {
        return leafPaths;
    }

    public WebActionHandlerRef getWebActionHandlerRef(String actionName) {
        return webActionHandlerDic.get(actionName);
    }

    public List<WebModelHandlerRef> getWebModelHandlerRefList(String[] resourcePaths){
        List<WebModelHandlerRef> refs = new ArrayList<WebModelHandlerRef>();
       
        // add the root
        WebModelHandlerRef rootWmr = getWebModeHandlerlRef("/");
        if (rootWmr != null) {
            refs.add(rootWmr);
        }
       
        StringBuilder pathBuilder = new StringBuilder();
        for (int i = 0; i < resourcePaths.length; i++) {
            String path = pathBuilder.append('/').append(resourcePaths[i]).toString();
            WebModelHandlerRef webModelRef = getWebModeHandlerlRef(path);
            if (webModelRef != null){
                refs.add(webModelRef);
            }
        }       
       
        return refs;
    }
   
    public WebModelHandlerRef getWebModeHandlerlRef(String path) {
        return webModelHandlerByStartsWithMap.get(path);
    }

    public List<WebModelHandlerRef> getMatchWebModelHandlerRef(String path) {
        List<WebModelHandlerRef> matchWebModelRefs = new ArrayList<WebModelHandlerRef>();

        for (WebModelHandlerRef webModelRef : webModelHandlerRefList) {
            boolean match = webModelRef.matchesPath(path);
            if (match) {
                matchWebModelRefs.add(webModelRef);
            }
        }

        return matchWebModelRefs;
    }

    public WebResourceHandlerRef getWebResourceHandlerRef(String path) {
        for (WebResourceHandlerRef webFileRef : webResourceHandlerList) {
            boolean match = webFileRef.matchesPath(path);
            if (match) {
                return webFileRef;
            }
        }
        return null;
    }

    /**
     * Do not call. Internal to Snow.
     *
     * (used by the FreemarkerTemplateRenderer)
     *
     * @return
     */
    public List<FreemarkerDirectiveProxy> getFreemarkerDirectiveProxyList() {
        return freemarkerDirectiveProxyList;
    }

    /**
     * Do not call. Internal to Snow.
     *
     * @param exceptionClass
     * @return
     */
    public List<FreemarkerMethodProxy> getFreemarkerMethodProxyList() {
        return freemarkerMethodProxyList;
    }

    public WebExceptionCatcherRef getWebExceptionCatcherRef(Class<? extends Throwable> exceptionClass) {
        WebExceptionCatcherRef ref = null;

        // if there is a direct match, return it.
        ref = webExceptionCatcherMap.get(exceptionClass);
        if (ref != null) {
            return ref;
        }

        Class cls = exceptionClass.getSuperclass();

        while (cls != Object.class) {
            ref = webExceptionCatcherMap.get(cls);
            if (ref != null) {
                return ref;
            }
            cls = cls.getSuperclass();
        }

        return null;
    }

    // --------- Private Registration Methods (call at init() time) --------- //
    private final void registerWebObjectMethods(Class webClass) {

        //Class c = getNonGuiceEnhancedClass(targetObject);
        Class c = webClass;
       
        Method methods[] = c.getMethods();
        List<String> additionalLeafPaths = new ArrayList<String>();

        for (Method m : methods) {
           
            // --------- Register Rest Methods --------- //
            WebGet webGet = m.getAnnotation(WebGet.class);
            if (webGet != null){
                restRegistry.registerWebRest(c, m, paramDefBuilder.buildParamDefs(m, true), HttpMethod.GET, webGet.value());
            }
           
            WebPost webPost = m.getAnnotation(WebPost.class);
            if (webPost != null){
                restRegistry.registerWebRest(c, m, paramDefBuilder.buildParamDefs(m, true), HttpMethod.POST, webPost.value());
            }
           
            WebPut webPut = m.getAnnotation(WebPut.class);
            if (webPut != null){
                restRegistry.registerWebRest(c, m, paramDefBuilder.buildParamDefs(m, true), HttpMethod.PUT, webPut.value());
            }
           
            WebDelete webDelete = m.getAnnotation(WebDelete.class);
            if (webDelete != null){
                restRegistry.registerWebRest(c, m, paramDefBuilder.buildParamDefs(m, true), HttpMethod.DELETE, webDelete.value());
            }           
            // --------- /Register Rest Methods --------- //
           
            // --------- Register Web Serializer --------- //
            WebSerializer webSerializer = m.getAnnotation(WebSerializer.class);
            if (webSerializer != null){
                serializerRegistry.registerWebSerializer(webClass, m, webSerializer);
            }
            // --------- /Register Web Serializer --------- //
           
            // --------- Register WebActionHandler --------- //
            WebActionHandler webActionHandlerAnnotation = m.getAnnotation(WebActionHandler.class);
            // if it is an action method, then, add the WebAction Object and
            // Method to the action Dic
            if (webActionHandlerAnnotation != null) {
                registerWebAction(c, m, webActionHandlerAnnotation);
            }
            // --------- /Register WebActionHandler --------- //

            // --------- Register WebModelHandler --------- //
            WebModelHandler webModelHandlerAnnotation = m.getAnnotation(WebModelHandler.class);
            if (webModelHandlerAnnotation != null) {
                registerWebModel(c, m, webModelHandlerAnnotation);
            }
            // --------- Register WebModelHandler --------- //

            // --------- Register WebResourceHandler --------- //
            WebResourceHandler webResourceHandlerAnnotation = m.getAnnotation(WebResourceHandler.class);
            if (webResourceHandlerAnnotation != null) {
                registerWebResourceHandler(c, m, webResourceHandlerAnnotation);
            }
            // --------- /Register WebResourceHandler --------- //

            // --------- Register WebRequestHook --------- //
            WebRequestHook webRequestHook = m.getAnnotation(WebRequestHook.class);
            if (webRequestHook != null) {
                hookRegistry.addReqHook(c, m, webRequestHook);
            }
            // --------- Register WebRequestHook --------- //

            // --------- Register WebRequestHook --------- //
            WebApplicationHook webApplicationHook = m.getAnnotation(WebApplicationHook.class);
            if (webApplicationHook != null) {
                hookRegistry.addAppHook(c, m, webApplicationHook);
            }
            // --------- Register WebRequestHook --------- //

            // --------- Freemarker handlers --------- //
            FreemarkerDirectiveHandler webTemplateDirective = m.getAnnotation(FreemarkerDirectiveHandler.class);
            if (webTemplateDirective != null) {
                registerFreemarkerDirective(c, m, webTemplateDirective);
            }

            FreemarkerMethodHandler freemarkerMethodHandler = m.getAnnotation(FreemarkerMethodHandler.class);
            if (freemarkerMethodHandler != null) {
                registerFreemarkerMethod(c, m, freemarkerMethodHandler);
            }
            // --------- /Freemarker handlers --------- //

            // --------- Register WebException --------- //
            WebExceptionCatcher webExceptionHandler = m.getAnnotation(WebExceptionCatcher.class);
            if (webExceptionHandler != null) {
                registerWebExceptionCatcher(c, m, webExceptionHandler);
            }
            // --------- /Register WebException --------- //

        }

        // if we have any declared leaf paths, add them into the array. they come after
        // any injected leaf path values.
        if (additionalLeafPaths.size() > 0) {
            if (leafPaths != null) {
                additionalLeafPaths.addAll(0, Arrays.asList(leafPaths));
            }

            leafPaths = additionalLeafPaths.toArray(new String[additionalLeafPaths.size()]);
        }
    }

    private final void registerWebModel(Class webClass, Method m, WebModelHandler webModel) {
        //WebParamResolverRef webParamResolverRefs[] = buildWebParamResolverRefs(m);
        WebModelHandlerRef webModelRef = new WebModelHandlerRef(webClass, m, paramDefBuilder.buildParamDefs(m,true), webModel);
        webModelHandlerRefList.add(webModelRef);

        String startWithArray[] = webModel.startsWith();
        for (String startsWith : startWithArray) {
            webModelHandlerByStartsWithMap.put(startsWith, webModelRef);
        }
    }

    private final void registerWebAction(Class webClass, Method m, WebActionHandler webAction) {

        String actionName = webAction.name();
        // if the action does have an empty name, then, take the name of the
        // method
        if (actionName.length() == 0) {
            actionName = m.getName();
        }
        // try to get the actionObjectList from the actionDic
        WebActionHandlerRef actionRef = webActionHandlerDic.get(actionName);
        // if the WebActionRef already exist, throw an exception
        if (actionRef != null) {
            // AlertHandler.systemSevere(Alert.ACTION_NAME_ALREADY_EXIST,
            // actionName);
            throw new RuntimeException("Action Name Already Exist: " + actionName);
        }
        // if not found, create an empty list
        // add this object and method to the list
        webActionHandlerDic.put(actionName, new WebActionHandlerRef(webClass, m, paramDefBuilder.buildParamDefs(m,true), webAction));
    }

    private final void registerWebResourceHandler(Class webClass, Method m, WebResourceHandler webResourceHandler) {
        WebResourceHandlerRef webFileRef = new WebResourceHandlerRef(webClass, m, paramDefBuilder.buildParamDefs(m,true), webResourceHandler);
        webResourceHandlerList.add(webFileRef);
    }

    private final void registerFreemarkerDirective(Class webClass, Method m,
                            FreemarkerDirectiveHandler freemarkerDirectiveHandler) {
        String templateMethodName = freemarkerDirectiveHandler.name();
        // if the action does have an empty name, then, take the name of the method
        if (templateMethodName.length() == 0) {
            templateMethodName = m.getName();
        }

        FreemakerDirectiveHandlerRef directiveRef = new FreemakerDirectiveHandlerRef(webClass, m, paramDefBuilder.buildParamDefs(m,true), freemarkerDirectiveHandler);
        FreemarkerDirectiveProxy directiveProxy = new FreemarkerDirectiveProxy(templateMethodName, directiveRef);
        injector.injectMembers(directiveProxy);
        freemarkerDirectiveProxyList.add(directiveProxy);
    }

    private final void registerFreemarkerMethod(Class webClass, Method m,
                            FreemarkerMethodHandler freemarkerMethodHandler) {
        String name = freemarkerMethodHandler.name();
        if (name.length() == 0) {
            name = m.getName();
        }
        FreemarkerMethodHandlerRef ref = new FreemarkerMethodHandlerRef(webClass, m, paramDefBuilder.buildParamDefs(m,true), freemarkerMethodHandler);
        FreemarkerMethodProxy proxy = new FreemarkerMethodProxy(name, ref);
        injector.injectMembers(proxy);
        freemarkerMethodProxyList.add(proxy);

    }

    private final void registerWebExceptionCatcher(Class cls, Method m, WebExceptionCatcher webExceptionHandler) {
        WebExceptionCatcherRef webExcpetionCatcherRef = new WebExceptionCatcherRef(cls, m, webExceptionHandler);
        webExceptionCatcherMap.put(webExcpetionCatcherRef.getThrowableClass(), webExcpetionCatcherRef);
    }

    // --------- /Private Registration Methods (call at init() time) --------- //

    public static Class getNonGuiceEnhancedClass(Object obj) {
        String className = obj.getClass().getName();
        if (className.indexOf("$$EnhancerByGuice$$") > -1) {
            return obj.getClass().getSuperclass();
        } else {
            return obj.getClass();
        }
    }

}
TOP

Related Classes of com.britesnow.snow.web.handler.WebObjectRegistry

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.