blob: 61fe830986fcda5116ce3ee1d9c2a20a011a30f3 [file] [log] [blame]
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you 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.apache.juneau.examples.rest;
import static org.apache.juneau.dto.html5.HtmlBuilder.*;
import static org.apache.juneau.http.HttpMethodName.*;
import org.apache.juneau.dto.html5.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
/**
* Service at <code>/codeFormatter</code>.
* Used for executing SQL queries against the repository database.
*/
@RestResource(
path="/codeFormatter",
messages="nls/CodeFormatterResource",
title="Code Formatter",
description="Utility for generating HTML code-formatted source code",
htmldoc=@HtmlDoc(
navlinks={
"up: servlet:/..",
"options: servlet:/?method=OPTIONS",
"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/$R{servletClassSimple}.java"
},
aside={
"<div style='min-width:200px' class='text'>",
" <p>Utility for adding code syntax tags to Java and XML/HTML code.</p>",
" <p>It's by no means perfect, but provides a good starting point.</p>",
"</div>"
},
style="aside {display:table-caption;}"
)
)
@SuppressWarnings({"serial"})
public class CodeFormatterResource extends BasicRestServlet {
/** [GET /] - Display query entry page. */
@RestMethod(name=GET, path="/")
public Div getQueryEntryPage(RestRequest req) {
return div(
script("text/javascript",
"\n // Quick and dirty function to allow tabs in textarea."
+"\n function checkTab(e) {"
+"\n if (e.keyCode == 9) {"
+"\n var t = e.target;"
+"\n var ss = t.selectionStart, se = t.selectionEnd;"
+"\n t.value = t.value.slice(0,ss).concat('\\t').concat(t.value.slice(ss,t.value.length));"
+"\n e.preventDefault();"
+"\n }"
+"\n }"
+"\n // Load results from IFrame into this document."
+"\n function loadResults(b) {"
+"\n var doc = b.contentDocument || b.contentWindow.document;"
+"\n var data = doc.getElementById('data') || doc.getElementsByTagName('body')[0];"
+"\n document.getElementById('results').innerHTML = data.innerHTML;"
+"\n }"
),
form("form").action("codeFormatter").method(POST).target("buff").children(
table(
tr(
th("Language: "),
td(
select().name("lang").children(
option("java","Java"),
option("xml", "XML")
)
),
td(button("submit", "Submit"), button("reset", "Reset"))
),
tr(
td().colspan(3).children(
textarea().name("code").style("min-width:800px;min-height:400px;font-family:Courier;font-size:9pt;").onkeydown("checkTab(event)")
)
)
)
),
br(),
div().id("results")._class("monospace"),
iframe().name("buff").style("display:none").onload("parent.loadResults(this)")
);
}
/** [POST /] - Add syntax highlighting to input. */
@RestMethod(name=POST, path="/")
public String executeQuery(@FormData("code") String code, @FormData("lang") String lang) throws Exception {
return highlight(code, lang);
}
private static String highlight(String code, String lang) throws Exception {
if (lang.equalsIgnoreCase("xml")) {
code = code.replaceAll("&", "&amp;");
code = code.replaceAll("<", "&lt;");
code = code.replaceAll(">", "&gt;");
code = code.replaceAll("(&lt;[^\\s&]+&gt;)", "<xt>$1</xt>");
code = code.replaceAll("(&lt;[^\\s&]+)(\\s)", "<xt>$1</xt>$2");
code = code.replaceAll("(['\"])(/?&gt;)", "$1<xt>$2</xt>");
code = code.replaceAll("([\\S]+)=", "<xa>$1</xa>=");
code = code.replaceAll("=(['\"][^'\"]+['\"])", "=<xs>$1</xs>");
} else if (lang.equalsIgnoreCase("java")) {
code = code.replaceAll("&", "&amp;");
code = code.replaceAll("<", "&lt;");
code = code.replaceAll(">", "&gt;");
code = code.replaceAll("(?s)(\\/\\*\\*.*?\\*\\/)", "<jd>$1</jd>"); // javadoc comments
code = code.replaceAll("(@\\w+)", "<ja>$1</ja>"); // annotations
code = code.replaceAll("(?s)(?!\\/)(\\/\\*.*?\\*\\/)", "<jc>$1</jc>"); // C style comments
code = code.replaceAll("(?m)(\\/\\/.*)", "<jc>$1</jc>"); // C++ style comments
code = code.replaceAll("(?m)('[^'\n]*'|\"[^\"\n]*\")", "<js>$1</js>"); // quotes
code = code.replaceAll("(?<!@)(import|package|boolean|byte|char|double|float|final|static|transient|synchronized|private|protected|public|int|long|short|abstract|class|interface|extends|implements|null|true|false|void|break|case|catch|continue|default|do|else|finally|for|goto|if|instanceof|native|new|return|super|switch|this|threadsafe|throws|throw|try|while)(?=\\W)", "<jk>$1</jk>"); // quotes
code = code.replaceAll("<\\/jk>(\\s+)<jk>", "$1"); // quotes
}
return code;
}
}