/*
* FindResult.java
*
* Copyright (C) 2009-12 by RStudio, Inc.
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.studio.client.workbench.views.output.find.model;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import org.rstudio.core.client.Pair;
import java.util.ArrayList;
public class FindResult extends JavaScriptObject
{
public static native FindResult create(String file,
int line,
String lineValue) /*-{
return ({
file: file,
line: line,
lineValue: lineValue
});
}-*/;
protected FindResult() {}
public native final String getFile() /*-{
return this.file;
}-*/;
public native final int getLine() /*-{
return this.line;
}-*/;
public native final String getLineValue() /*-{
return this.lineValue;
}-*/;
public final ArrayList<Integer> getMatchOns()
{
return getJavaArray("matchOn");
}
public final ArrayList<Integer> getMatchOffs()
{
return getJavaArray("matchOff");
}
public final SafeHtml getLineHTML()
{
SafeHtmlBuilder out = new SafeHtmlBuilder();
ArrayList<Integer> on = getMatchOns();
ArrayList<Integer> off = getMatchOffs();
ArrayList<Pair<Boolean, Integer>> parts
= new ArrayList<Pair<Boolean, Integer>>();
while (on.size() + off.size() > 0)
{
int onVal = on.size() == 0 ? Integer.MAX_VALUE : on.get(0);
int offVal = off.size() == 0 ? Integer.MAX_VALUE : off.get(0);
if (onVal <= offVal)
parts.add(new Pair<Boolean, Integer>(true, on.remove(0)));
else
parts.add(new Pair<Boolean, Integer>(false, off.remove(0)));
}
String line = getLineValue();
// Use a counter to ensure tags are balanced.
int openTags = 0;
for (int i = 0; i < line.length(); i++)
{
while (parts.size() > 0 && parts.get(0).second == i)
{
if (parts.remove(0).first)
{
out.appendHtmlConstant("<strong>");
openTags++;
}
else if (openTags > 0)
{
out.appendHtmlConstant("</strong>");
openTags--;
}
}
out.append(line.charAt(i));
}
while (openTags > 0)
{
openTags--;
out.appendHtmlConstant("</strong>");
}
return out.toSafeHtml();
}
private ArrayList<Integer> getJavaArray(String property)
{
JsArrayInteger array = getArray(property);
ArrayList<Integer> ints = new ArrayList<Integer>();
for (int i = 0; i < array.length(); i++)
ints.add(array.get(i));
return ints;
}
private native final JsArrayInteger getArray(String property) /*-{
if (this == null)
return [];
return this[property] || [];
}-*/;
}