/*
This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along
with this program; if not, see http://www.gnu.org/licenses or write to the Free
Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
package com.servoy.j2db.server.headlessclient.dataui;
import java.util.ArrayList;
import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.util.crypt.ICrypt;
import com.servoy.j2db.ExitScriptException;
import com.servoy.j2db.server.headlessclient.WebForm;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.Utils;
/**
* The behavior used by components that want to eval a specific scriptname on the current form.
*
* @author jcompagner
*
* @see ISupportScriptCallback
* @see WebDataHtmlView
*/
public final class InlineScriptExecutorBehavior extends AbstractServoyDefaultAjaxBehavior
{
static final String BROWSER_PARAM = "browser:";
/**
*
*/
private final Component component;
/**
* @param webDataHtmlView
*/
InlineScriptExecutorBehavior(Component component)
{
this.component = component;
}
private static final long serialVersionUID = 1L;
@Override
protected void respond(AjaxRequestTarget target)
{
Page page = component.getPage();
String scriptName = RequestCycle.get().getRequest().getParameter("snenc");
ICrypt urlCrypt = Application.get().getSecuritySettings().getCryptFactory().newCrypt();
scriptName = urlCrypt.decryptUrlSafe(scriptName).replace("\\\"", "\"");
String argValue;
for (String browserArgument : getBrowserArguments(scriptName))
{
argValue = RequestCycle.get().getRequest().getParameter(browserArgument);
if (argValue == null) argValue = "";
boolean isString = true;
try
{
Double.parseDouble(argValue);
isString = false;
}
catch (NumberFormatException ex)
{
}
if (isString && ("true".equals(argValue) || "false".equals(argValue))) isString = false;
String browserParamWithArgument = BROWSER_PARAM + browserArgument;
// make sure we ignore user quoting if isString
if (isString)
{
scriptName = scriptName.replace("\"" + browserParamWithArgument + "\"", browserParamWithArgument);
scriptName = scriptName.replace("'" + browserParamWithArgument + "'", browserParamWithArgument);
}
scriptName = scriptName.replace(browserParamWithArgument, isString ? "'" + argValue + "'" : argValue);
}
WebForm wf = component.findParent(WebForm.class);
if (wf != null)
{
try
{
wf.getController().eval(scriptName);
}
catch (Exception e)
{
if (!(e instanceof ExitScriptException))
{
Debug.error("Exception evaluating: " + scriptName, e); //$NON-NLS-1$
}
}
WebEventExecutor.generateResponse(target, page);
}
target.appendJavascript("clearDoubleClickId('" + component.getMarkupId() + "')"); //$NON-NLS-1$ //$NON-NLS-2$
}
ArrayList<String> getBrowserArguments(String s)
{
ArrayList<String> browserArguments = new ArrayList<String>();
String escapedScriptName = Utils.stringReplace(Utils.stringReplace(s, "\'", "\\\'"), "\"", """);
int browserVariableIndex = escapedScriptName.indexOf(BROWSER_PARAM);
if (browserVariableIndex != -1)
{
while (browserVariableIndex != -1)
{
// is there a next variable
int index = searchEndVariable(escapedScriptName, browserVariableIndex + 8);
if (index == -1)
{
Debug.error("illegal script name encountered with browser arguments: " + escapedScriptName);
break;
}
else
{
browserArguments.add(escapedScriptName.substring(browserVariableIndex + 8, index));
browserVariableIndex = escapedScriptName.indexOf(BROWSER_PARAM, index);
}
}
}
return browserArguments;
}
/**
* @param escapedScriptName
* @param i
* @return
*/
private int searchEndVariable(String script, int start)
{
int counter = start;
int brace = 0;
while (counter < script.length())
{
switch (script.charAt(counter))
{
case '\\' :
if (brace == 0) return counter;
break;
case '&' :
if (brace == 0) return counter;
break;
case '\'' :
if (brace == 0) return counter;
break;
case ',' :
if (brace == 0) return counter;
break;
case '(' :
brace++;
break;
case ')' :
if (brace == 0) return counter;
brace--;
break;
}
counter++;
}
return 0;
}
}