package org.h3270.render;
/*
* Copyright (C) 2003-2008 akquinet tech@spree
*
* This file is part of h3270.
*
* h3270 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 3 of the License, or
* (at your option) any later version.
*
* h3270 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 h3270; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import org.h3270.host.InputField;
import org.h3270.host.Screen;
import org.h3270.host.ScreenCharSequence;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.h3270.web.SessionState;
/**
* @author Andre Spiegel spiegel@gnu.org
* @version $Id: RegexRenderer.java,v 1.18 2008/11/21 14:48:32 spiegel Exp $
*/
public class RegexRenderer extends HtmlRenderer {
private Pattern acceptPattern = null;
private Pattern matchPattern = null;
private String htmlTemplate = null;
private static final Pattern FILE_PATTERN =
Pattern.compile ( "^<!-- accept\\n(.*?)\\n^-->\\s+"
+ "^<!-- match\\n(.*?)\\n^-->\\s+"
+ "(.*)",
Pattern.MULTILINE | Pattern.DOTALL);
public RegexRenderer (String filename) {
try {
BufferedReader input = new BufferedReader (new FileReader (filename));
StringBuffer contents = new StringBuffer();
while (true) {
String line = input.readLine();
if (line == null) break;
contents.append (line);
contents.append ("\n");
}
Matcher m = FILE_PATTERN.matcher (contents);
if (m.find()) {
acceptPattern = Pattern.compile (m.group(1));
matchPattern = Pattern.compile (m.group(2), Pattern.DOTALL);
htmlTemplate = m.group(3);
} else
throw new RuntimeException ("could not parse template " + filename);
} catch (IOException ex) {
throw new RuntimeException ("IOException while reading " + filename +
" " + ex);
}
}
public boolean canRender (Screen s) {
return canRender (new TextRenderer().render(s));
}
public boolean canRender (String screenText) {
Matcher m = acceptPattern.matcher (screenText);
return m.find();
}
/**
* Pattern that finds placeholders such as #1, #2, #3 within
* template pages. Mind the negative lookbehind at the beginning,
* because we don't want HTML character references (xx;) to count
* as placeholders!
*/
private static final Pattern PLACEHOLDER_PATTERN =
Pattern.compile ("(?<!&)#([0-9]+)(?:\\{(.*?)\\})?");
public String render (Screen s, String actionURL, String id) {
ScreenCharSequence screenSeq = new ScreenCharSequence(s);
Matcher m = matchPattern.matcher(screenSeq.toString());
if (m.find()) {
// Generate HTML page from template, replacing placeholders
// in the template with matches from the matchPattern.
StringBuffer result = new StringBuffer();
result.append ("<form id=\"" + getFormName(id) + "\" "
+ "action=\"" + actionURL + "\" "
+ "method=\"post\">\n");
Matcher placeholder = PLACEHOLDER_PATTERN.matcher (htmlTemplate);
int index = 0;
while (placeholder.find()) {
result.append (htmlTemplate.substring (index, placeholder.start()));
int number = Integer.parseInt (placeholder.group(1));
String filterName = placeholder.group(2);
String replacement = m.group(number);
if (replacement.startsWith("{"))
renderInputField (result,
(InputField)screenSeq.getFieldAt(m.start(number)+1),
id);
else if (filterName != null)
result.append (getFilter(filterName).filter(replacement));
else
result.append (replacement);
index = placeholder.end();
}
result.append (htmlTemplate.substring (index));
result.append ("<div><input type=\"hidden\" name=\"key\" /></div>\n");
if (id != null) {
result.append ("<div><input type=\"hidden\" name=\""
+ SessionState.TERMINAL + "\" value=\""
+ id + "\"></div>\n");
}
result.append ("</form>");
appendFocus (s, id, result);
return result.toString();
} else
return "no match";
}
public String render (Screen s) {
return this.render (s, "");
}
private Filter getFilter (String name) {
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clz = cl.loadClass(name);
Filter result = (Filter)clz.newInstance();
return result;
} catch (Exception ex) {
throw new RuntimeException ("error: " + ex);
}
}
// public static void main(String[] args) {
// String path = "/home/spiegel/com/h3270/";
// RegexRenderer r = new RegexRenderer
// (path + "templates/dr-tpx.html");
// Screen s = new S3270Screen(path + "dump/dr-1.edump");
// if (r.canRender(s))
// System.out.println(r.render(s));
// else
// System.out.println("no match");
// }
}