com.gargoylesoftware.htmlunit.javascript.regexp.HtmlUnitRegExpProxy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vaadin-client-compiler-deps Show documentation
Show all versions of vaadin-client-compiler-deps Show documentation
Vaadin is a web application framework for Rich Internet Applications (RIA).
Vaadin enables easy development and maintenance of fast and
secure rich web
applications with a stunning look and feel and a wide browser support.
It features a server-side architecture with the majority of the logic
running
on the server. Ajax technology is used at the browser-side to ensure a
rich
and interactive user experience.
/*
* Copyright (c) 2002-2011 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gargoylesoftware.htmlunit.javascript.regexp;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.RegExpProxy;
import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.regexp.NativeRegExp;
import net.sourceforge.htmlunit.corejs.javascript.regexp.RegExpImpl;
import net.sourceforge.htmlunit.corejs.javascript.regexp.SubString;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Begins customization of JavaScript RegExp base on JDK regular expression support.
*
* @version $Revision: 6335 $
* @author Marc Guillemot
* @author Ahmed Ashour
* @author Ronald Brill
*/
public class HtmlUnitRegExpProxy extends RegExpImpl {
private static final Log LOG = LogFactory.getLog(HtmlUnitRegExpProxy.class);
private static final Pattern REPLACE_PATTERN = Pattern.compile("\\$\\$");
private final RegExpProxy wrapped_;
/**
* Wraps a proxy to enhance it.
* @param wrapped the original proxy
*/
public HtmlUnitRegExpProxy(final RegExpProxy wrapped) {
wrapped_ = wrapped;
}
/**
* Use the wrapped proxy except for replacement with string arg where it uses Java regular expression.
* {@inheritDoc}
*/
@Override
public Object action(final Context cx, final Scriptable scope, final Scriptable thisObj,
final Object[] args, final int actionType) {
try {
return doAction(cx, scope, thisObj, args, actionType);
}
catch (final StackOverflowError e) {
// TODO: We shouldn't have to catch this exception and fall back to Rhino's regex support!
// See HtmlUnitRegExpProxyTest.stackOverflow()
LOG.warn(e.getMessage(), e);
return wrapped_.action(cx, scope, thisObj, args, actionType);
}
}
private Object doAction(final Context cx, final Scriptable scope, final Scriptable thisObj,
final Object[] args, final int actionType) {
// in a first time just improve replacement with a String (not a function)
if (RA_REPLACE == actionType && args.length == 2 && (args[1] instanceof String)) {
final String thisString = Context.toString(thisObj);
String replacement = (String) args[1];
final Object arg0 = args[0];
if (arg0 instanceof String) {
replacement = REPLACE_PATTERN.matcher(replacement).replaceAll("\\$");
// arg0 should *not* be interpreted as a RegExp
return StringUtils.replaceOnce(thisString, (String) arg0, replacement);
}
else if (arg0 instanceof NativeRegExp) {
try {
final NativeRegExp regexp = (NativeRegExp) arg0;
final RegExpData reData = new RegExpData(regexp);
final String regex = reData.getJavaPattern();
final int flags = reData.getJavaFlags();
final Pattern pattern = Pattern.compile(regex, flags);
final Matcher matcher = pattern.matcher(thisString);
return doReplacement(thisString, replacement, matcher, reData.hasFlag('g'));
}
catch (final PatternSyntaxException e) {
LOG.warn(e.getMessage(), e);
}
}
}
else if (RA_MATCH == actionType || RA_SEARCH == actionType) {
if (args.length == 0) {
return null;
}
final Object arg0 = args[0];
final String thisString = Context.toString(thisObj);
final RegExpData reData;
if (arg0 instanceof NativeRegExp) {
reData = new RegExpData((NativeRegExp) arg0);
}
else {
reData = new RegExpData(Context.toString(arg0));
}
final Pattern pattern = Pattern.compile(reData.getJavaPattern(), reData.getJavaFlags());
final Matcher matcher = pattern.matcher(thisString);
final boolean found = matcher.find();
if (RA_SEARCH == actionType) {
if (found) {
setProperties(matcher, thisString, matcher.start(), matcher.end());
return matcher.start();
}
return -1;
}
if (!found) {
return null;
}
final int index = matcher.start(0);
final List