/*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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 org.kie.workbench.common.screens.javaeditor.client.widget;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
public class ViewJavaSourceWidget extends Composite {
private final FlexTable table = new FlexTable();
public ViewJavaSourceWidget() {
initWidget( table );
}
public void setContent( final String content ) {
clearContent();
final String[] rows = content.split( "\n" );
boolean inSideBlockComment = false;
boolean lineComment = false;
for ( int i = 0; i < rows.length; i++ ) {
String s = rows[i].trim();
// Only evaluate if a line starts with '/*' if you're not already inside one
if (!inSideBlockComment) inSideBlockComment = s.startsWith( "/*" );
lineComment = !inSideBlockComment && s.startsWith( "//" );
// Escape leading white spaces and html brackets BEFORE applying syntax highlighting
// (which wraps the text with '<span ...')
String escaped = replaceLeadingWhitespaces( rows [ i ] );
escaped = escapeHtmlBrackets( escaped );
table.setHTML( i,
0,
"<span style='font-family:monospace; color:grey;'>"
+ ( i + 1 )
+ ".</span>" );
table.setHTML( i,
1,
"<span style='font-family:monospace; color:green;' >|</span>" );
table.setHTML( i,
2,
addSyntaxHighlights( escaped, inSideBlockComment || lineComment )
);
// While inside a block comment, evaluate if line ends with '*/'
if (inSideBlockComment) inSideBlockComment = !s.endsWith("*/");
}
}
public void clearContent() {
table.removeAllRows();
}
private String replaceLeadingWhitespaces( String text ) {
String s = text.trim();
if ( s.length() == 0) return "";
StringBuilder sb = new StringBuilder("");
int i = 0;
while ( ' ' == text.charAt( i ) ) {
sb.append( " " );
i++;
}
sb.append( text.substring( i ) );
return sb.toString();
}
private String escapeHtmlBrackets( String s ) {
return s.replaceAll( "<", "<" ).replaceAll( ">", ">" );
}
private String addSyntaxHighlights( String text, boolean isComment ) {
if ( isComment ) {
text = "<span style='font-family:monospace; color:green'>"
+ text
+ "</span>";
} else {
String [] kws = {
"abstract", "continue", "for", "new", "switch",
"assert", "default", "if", "package", "synchronized",
"boolean", "do", "goto", "private", "this",
"break", "double", "implements", "protected", "throw",
"byte", "else", "import", "public", "throws",
"case", "enum", "instanceof", "return", "transient",
"catch", "extends", "int", "short", "try",
"char", "final", "interface", "static", "void",
"class", "finally", "long", "strictfp", "volatile",
"const", "float", "native", "super", "while",
// literals
"null", "true", "false"
};
for ( String keyword : kws ) {
final String match = "\\b" + keyword + "\\b";
text = text.replaceAll( match, "<span style='font-family:monospace; color:red;'>"
+ keyword
+ "</span>" );
}
text = handleStrings( "\"", text );
}
return text;
}
private String handleStrings( String character,
String text ) {
int stringStart = text.indexOf( character );
while ( stringStart >= 0 ) {
int stringEnd = text.indexOf( character,
stringStart + 1 );
if ( stringEnd < 0 ) {
stringStart = -1;
break;
}
String oldString = text.substring( stringStart,
stringEnd + 1 );
String newString = "<span style='font-family:monospace; color:green;'>"
+ oldString
+ "</span>";
String beginning = text.substring( 0,
stringStart );
String end = text.substring( stringEnd + 1 );
text = beginning
+ newString
+ end;
int searchStart = stringStart
+ newString.length()
+ 1;
if ( searchStart < text.length() ) {
stringStart = text.indexOf( character,
searchStart );
} else {
stringStart = -1;
}
}
return text;
}
}