/*
* SmartDoc : Ultimate document format based on XML
* Copyright (C) 1998-2004 ASAMI, Tomoharu (asami@XMLSmartDoc.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.xmlsmartdoc.SmartDoc.normalizer;
import java.util.*;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.perl.Perl5Util;
import com.AsamiOffice.text.UString;
import org.xmlsmartdoc.SmartDoc.*;
/**
* JavaSourceNormalizer
*
* @since Mar. 31, 2000
* @version Jan. 25, 2004
* @author ASAMI, Tomoharu (asami@XMLSmartDoc.org)
* @author SAKURAI, Masashi
*/
public class JavaSourceNormalizer extends AbstractNormalizer {
protected Content[] _normalize(
Content[] contents,
Content parent,
DocContext context
) {
String keywordRegex = UString.checkNull(
parent.getAttribute("javasrcKeyword")
);
String keywordCount = UString.checkNull(
parent.getAttribute("javasrcCount")
);
String hilightRegex = UString.checkNull(
parent.getAttribute("javasrcHilight")
);
String syntaxHilight = UString.checkNull(
parent.getAttribute("javasrcSyntaxHilight")
);
String text = UDoc.makeInlineText((Container)parent);
Perl5Util util = new Perl5Util();
if (keywordRegex != null) {
int count = 1;
if (keywordCount != null) {
try {
count = Integer.parseInt(keywordCount);
} catch (NumberFormatException e) {
}
}
if (_isMatch(util, keywordRegex, text, count)) {
String matched = util.toString();
int start = _getStart(text, matched, count);
if (start == -1) {
throw (new InternalError());
}
int finish = start + matched.length();
start = RegexNormalizer.adjustStart(text, start);
finish = adjustBody(text, start);
finish = RegexNormalizer.adjustFinish(text, finish);
text = text.substring(start, finish);
} else {
text = "JavaSource normalizer : no match [" +
keywordRegex + "]";
}
}
parent.setText(null); // XXX
List list = new ArrayList();
// modified by SAKURAI, Masashi
if ("true".equals(syntaxHilight)) {
makeJavaHilight(text,list);
} else {
RegexNormalizer.makeHilight(hilightRegex, text, list);
}
// modified end
return (UDoc.list2Contents(list));
}
private static boolean _isMatch(
Perl5Util util,
String keywordRegex,
String text,
int count
) {
PatternMatcherInput input = new PatternMatcherInput(text);
String expr = "#" + keywordRegex + "#m";
while (util.match(expr, input)) {
if (--count == 0) {
return (true);
}
}
return (false);
}
private static int _getStart(String text, String matched, int count) {
int index = 0;
for (;;) {
index = text.indexOf(matched, index);
if (index == -1) {
return (-1);
}
if (--count == 0) {
return (index);
}
index += matched.length();
}
}
public static int adjustBody(String text, int position) {
int size = text.length();
int lines = 0;
int point;
boolean inParentheses = false;
for (point = position;point < size;point++) {
int c = text.charAt(point);
if (c == '\n') {
if (!inParentheses) {
lines++;
}
if (lines == 2) {
return (position);
}
}
if (c == '{') {
break;
}
if (c == '(') {
inParentheses = true;
} else if (c == ')') {
inParentheses = false;
}
}
if (point == size) {
return (position);
}
int count = 1;
// XXX : String, comment
for (point++;point < size;point++) {
int c = text.charAt(point);
if (c == '}') {
count--;
if (count == 0) {
return (point);
}
} else if (c == '{') {
count++;
}
}
return (point);
}
//
// created by SAKURAI, Masashi
//
/** make hilight for java syntax */
protected static void makeJavaHilight(String text,List list) {
if (hilighter == null) {
String [][] keymatrix = {keywords,primitives,comments,quotes};
hilighter = new HilightMaker(keymatrix,isRegex,classes);
}
hilighter.makeHilight(text,list);
}
// Hilight Maker
protected static HilightMaker hilighter = null;
// Target node class name and CSS class name
// # {keywords, primitives, comments, quotes}
protected static String [] classes = {
"org.xmlsmartdoc.SmartDoc.Span#keyword",
"org.xmlsmartdoc.SmartDoc.Span#primitive",
"org.xmlsmartdoc.SmartDoc.Span#comment",
"org.xmlsmartdoc.SmartDoc.Span#quote"};
// regex or just keyword switch
// # if keyword-searching needs regex search, set true.
// # this switch exists for just performance improvement.
// # {keywords, primitives, comments, quotes}
protected static boolean [] isRegex = {false,false,true,true};
// array of keywords for coloring
protected static String [] keywords = {
"public","protected","private","abstract","final","transient","native",
"class","interface","extends","implements","static","import",
"for","while","if","do","else","swith","case","throws","package",
"try","catch","finally","synchronized","default","new","return"};
protected static String [] primitives = {
"short","byte","int","long","float","double","char","String",
"boolean","void","null","false","true"};
// regex for single, multiple line, formal comment
protected static String [] comments = {"//.*$", "/\\*[^/](.|\\s)*?\\*/","/\\*\\*[^/](.|\\s)*?\\*/"};
// regex for string literal
protected static String [] quotes = {"\\\".*?\\\""};
//
// created end
//
}