001// Copyright 2007, 2008, 2009, 2010 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007// http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry5.internal.services;
016
017import org.apache.tapestry5.Field;
018import org.apache.tapestry5.Link;
019import org.apache.tapestry5.corelib.data.InsertPosition;
020import org.apache.tapestry5.json.JSONArray;
021import org.apache.tapestry5.json.JSONLiteral;
022import org.apache.tapestry5.json.JSONObject;
023import org.apache.tapestry5.services.ClientBehaviorSupport;
024import org.apache.tapestry5.services.Environment;
025import org.apache.tapestry5.services.FormSupport;
026import org.apache.tapestry5.services.javascript.JavaScriptSupport;
027
028public class ClientBehaviorSupportImpl implements ClientBehaviorSupport
029{
030    private final JavaScriptSupport javascriptSupport;
031
032    private final Environment environment;
033
034    private final JSONObject validations = new JSONObject();
035
036    public ClientBehaviorSupportImpl(JavaScriptSupport javascriptSupport, Environment environment)
037    {
038        this.javascriptSupport = javascriptSupport;
039        this.environment = environment;
040    }
041
042    public void addZone(String clientId, String showFunctionName, String updateFunctionName)
043    {
044        JSONObject spec = new JSONObject("element", clientId);
045
046        addFunction(spec, "show", showFunctionName);
047        addFunction(spec, "update", updateFunctionName);
048
049        FormSupport formSupport = environment.peek(FormSupport.class);
050
051        if (formSupport != null)
052        {
053            JSONObject parameters = new JSONObject(RequestConstants.FORM_CLIENTID_PARAMETER, formSupport.getClientId(),
054                    RequestConstants.FORM_COMPONENTID_PARAMETER, formSupport.getFormComponentId());
055            spec.put("parameters", parameters);
056        }
057
058        javascriptSupport.addInitializerCall("zone", spec);
059    }
060
061    private void addFunction(JSONObject spec, String key, String functionName)
062    {
063        if (functionName != null)
064            spec.put(key, functionName.toLowerCase());
065    }
066
067    public void linkZone(String linkId, String elementId, Link eventLink)
068    {
069        JSONObject spec = new JSONObject("linkId", linkId, "zoneId", elementId, "url", eventLink.toURI());
070
071        javascriptSupport.addInitializerCall("linkZone", spec);
072    }
073
074    /**
075     * @deprecated Use {@link #addFormFragment(String,boolean,String,String)} instead
076     */
077    public void addFormFragment(String clientId, String showFunctionName, String hideFunctionName)
078    {
079        addFormFragment(clientId, false, showFunctionName, hideFunctionName, null);
080    }
081
082    /**
083     * @deprecated Use {@link #addFormFragment(String, boolean, String, String, String)} instead
084     */
085    public void addFormFragment(String clientId, boolean alwaysSubmit, String showFunctionName, String hideFunctionName)
086    {
087        addFormFragment(clientId, false, showFunctionName, hideFunctionName, null);
088    }
089
090    public void addFormFragment(String clientId, boolean alwaysSubmit, String showFunctionName, String hideFunctionName, String visibilityBoundFunctionName)
091    {
092        JSONObject spec = new JSONObject("element", clientId);
093
094        addFunction(spec, "show", showFunctionName);
095        addFunction(spec, "hide", hideFunctionName);
096
097        if (visibilityBoundFunctionName != null)
098            spec.put("bound", new JSONLiteral(visibilityBoundFunctionName));
099
100        if (alwaysSubmit)
101            spec.put("alwaysSubmit", true);
102
103        javascriptSupport.addInitializerCall("formFragment", spec);
104    }
105
106    public void addFormInjector(String clientId, Link link, InsertPosition insertPosition, String showFunctionName)
107    {
108        JSONObject spec = new JSONObject("element", clientId, "url", link.toURI());
109
110        if (insertPosition == InsertPosition.BELOW)
111            spec.put("below", true);
112
113        addFunction(spec, "show", showFunctionName);
114
115        // Always has at least two properties.
116
117        javascriptSupport.addInitializerCall("formInjector", spec);
118    }
119
120    public void addValidation(Field field, String validationName, String message, Object constraint)
121    {
122        String fieldId = field.getClientId();
123
124        JSONArray specs;
125
126        if (validations.has(fieldId))
127            specs = validations.getJSONArray(fieldId);
128        else
129        {
130            specs = new JSONArray();
131            validations.put(fieldId, specs);
132        }
133
134        JSONArray thisSpec = new JSONArray();
135
136        thisSpec.put(validationName);
137        thisSpec.put(message);
138
139        if (constraint != null)
140            thisSpec.put(constraint);
141
142        specs.put(thisSpec);
143    }
144
145    /**
146     * Invoked at the end of rendering to commit (to the {@link JavaScriptSupport}) any accumulated
147     * validations.
148     */
149    public void commit()
150    {
151        if (validations.length() != 0)
152            javascriptSupport.addInitializerCall("validate", validations);
153    }
154}