001    /*
002     * Apache License
003     * Version 2.0, January 2004
004     * http://www.apache.org/licenses/
005     *
006     * Copyright 2008-2010 by chenillekit.org
007     *
008     * Licensed under the Apache License, Version 2.0 (the "License");
009     * you may not use this file except in compliance with the License.
010     * You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     */
014    
015    package org.chenillekit.tapestry.core.base;
016    
017    import org.apache.tapestry5.ClientElement;
018    import org.apache.tapestry5.ComponentEventCallback;
019    import org.apache.tapestry5.ComponentResources;
020    import org.apache.tapestry5.Link;
021    import org.apache.tapestry5.annotations.Environmental;
022    import org.apache.tapestry5.annotations.Import;
023    import org.apache.tapestry5.annotations.InjectContainer;
024    import org.apache.tapestry5.annotations.MixinAfter;
025    import org.apache.tapestry5.annotations.Parameter;
026    import org.apache.tapestry5.internal.util.Holder;
027    import org.apache.tapestry5.ioc.annotations.Inject;
028    import org.apache.tapestry5.services.Request;
029    import org.apache.tapestry5.services.javascript.JavaScriptSupport;
030    
031    import java.util.List;
032    
033    /**
034     * @version $Id: AbstractEventMixin.java 674 2010-07-29 12:47:25Z homburgs $
035     */
036    @Import(library = {"../Chenillekit.js", "../components/CkOnEvents.js"})
037    @MixinAfter
038    abstract public class AbstractEventMixin implements EventMixin
039    {
040            private static String EVENT_NAME = "internalEvent";
041    
042            private static String PARAM_NAME = "value";
043    
044            @Inject
045            private Request request;
046    
047            @Inject
048            private ComponentResources resources;
049    
050            @InjectContainer
051            private ClientElement clientElement;
052    
053            /**
054             * the javascript callback function (optional).
055             * function has one parameter: the response text
056             */
057            @Parameter(required = false, defaultPrefix = "literal")
058            private String onCompleteCallback;
059    
060            /**
061             * <a href="http://www.prototypejs.org/api/event/stop">Event.stop</a>
062             */
063            @Parameter(required = false, defaultPrefix = "literal")
064            private boolean stop;
065    
066            /**
067             * The context for the link (optional parameter). This list of values will be converted into strings and included in
068             * the URI. The strings will be coerced back to whatever their values are and made available to event handler
069             * methods.
070             */
071            @Parameter
072            private List<?> context;
073    
074            @Environmental
075            private JavaScriptSupport javascriptSupport;
076    
077            private Object[] contextArray;
078    
079            /**
080             * get the conext parameter(s)
081             *
082             * @return conext parameter(s)
083             */
084            public List<?> getContext()
085            {
086                    return context;
087            }
088    
089            void setupRender()
090            {
091                    contextArray = context == null ? new Object[0] : context.toArray();
092            }
093    
094            void afterRender()
095            {
096                    Link link = resources.createEventLink(EVENT_NAME, contextArray);
097                    String id = clientElement.getClientId();
098    
099                    String jsString = "new Ck.OnEvent('%s', '%s', %b, '%s', '%s');";
100                    String callBackString = resources.isBound("onCompleteCallback") ? onCompleteCallback : "";
101                    boolean doStop = resources.isBound("stop") && stop;
102    
103                    javascriptSupport.addScript(jsString, getEventName(), id, doStop, link.toAbsoluteURI(), callBackString);
104            }
105    
106            Object onInternalEvent()
107            {
108                    String input = request.getParameter(PARAM_NAME);
109    
110                    final Holder<Object> valueHolder = Holder.create();
111    
112                    ComponentEventCallback callback = new ComponentEventCallback<Object>()
113                    {
114                            public boolean handleResult(Object result)
115                            {
116                                    valueHolder.put(result);
117                                    return true;
118                            }
119                    };
120    
121                    resources.triggerEvent(getEventName(), new Object[]{input}, callback);
122    
123                    return valueHolder.get();
124            }
125    }