/*
GNU GENERAL LICENSE
Copyright (C) 2006 The Lobo Project. Copyright (C) 2014 - 2017 Lobo Evolution
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
verion 3 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 License for more details.
You should have received a copy of the GNU General Public
along with this program. If not, see <http://www.gnu.org/licenses/>.
Contact info: lobochief@users.sourceforge.net; ivan.difrancesco@yahoo.it
*/
package org.lobobrowser.html.test;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Frame;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import org.lobobrowser.html.HtmlRendererContext;
import org.lobobrowser.html.gui.HtmlPanel;
import org.lobobrowser.html.style.CSSUtilities;
import org.lobobrowser.http.UserAgentContext;
import org.lobobrowser.util.SSLCertificate;
import org.lobobrowser.util.io.IORoutines;
import org.w3c.css.sac.InputSource;
import org.w3c.dom.css.CSSImportRule;
import org.w3c.dom.css.CSSRule;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSStyleRule;
import org.w3c.dom.css.CSSStyleSheet;
import com.steadystate.css.parser.CSSOMParser;
/**
* Tests only the CSS parser.
*/
public class CssParserTest extends JFrame {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The Constant logger. */
private static final Logger logger = LogManager.getLogger(CssParserTest.class);
/** The css output. */
private final HtmlPanel cssOutput;
/** The text area. */
private final JTextArea textArea;
/**
* Instantiates a new css parser test.
*
* @throws HeadlessException
* the headless exception
*/
public CssParserTest() throws HeadlessException {
this("CSS Parser Test Tool");
}
/**
* Instantiates a new css parser test.
*
* @param title
* the title
* @throws HeadlessException
* the headless exception
*/
public CssParserTest(String title) throws HeadlessException {
super(title);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = this.getContentPane();
contentPane.setLayout(new BorderLayout());
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
final JTextField textField = new JTextField();
JButton button = new JButton("Parse & Render");
final JTabbedPane tabbedPane = new JTabbedPane();
HtmlPanel htmlPanel = new HtmlPanel();
this.cssOutput = htmlPanel;
contentPane.add(topPanel, BorderLayout.NORTH);
contentPane.add(bottomPanel, BorderLayout.CENTER);
topPanel.add(new JLabel("URL: "), BorderLayout.WEST);
topPanel.add(textField, BorderLayout.CENTER);
topPanel.add(button, BorderLayout.EAST);
bottomPanel.add(tabbedPane, BorderLayout.CENTER);
final JTextArea textArea = new JTextArea();
this.textArea = textArea;
final JScrollPane textAreaSp = new JScrollPane(textArea);
tabbedPane.addTab("Parsed CSS", htmlPanel);
tabbedPane.addTab("Source Code", textAreaSp);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
process(textField.getText());
}
});
}
/**
* Process.
*
* @param uri
* the uri
*/
private void process(String uri) {
try {
URL url;
try {
url = new URL(uri);
} catch (MalformedURLException mfu) {
int idx = uri.indexOf(':');
if ((idx == -1) || (idx == 1)) {
// try file
url = new URL("file:" + uri);
} else {
throw mfu;
}
}
logger.info("process(): Loading URI=[" + uri + "].");
long time0 = System.currentTimeMillis();
SSLCertificate.setCertificate();
URLConnection connection = url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible;) Cobra/0.96.1+");
connection.setRequestProperty("Cookie", "");
if (connection instanceof HttpURLConnection) {
HttpURLConnection hc = (HttpURLConnection) connection;
hc.setInstanceFollowRedirects(true);
int responseCode = hc.getResponseCode();
logger.info("process(): HTTP response code: " + responseCode);
}
InputStream in = connection.getInputStream();
byte[] content;
try {
content = IORoutines.load(in, 8192);
} finally {
in.close();
}
String source = new String(content, "UTF-8");
this.textArea.setText(source);
long time1 = System.currentTimeMillis();
CSSOMParser parser = new CSSOMParser();
InputSource is = CSSUtilities.getCssInputSourceForStyleSheet(source, uri);
CSSStyleSheet styleSheet = parser.parseStyleSheet(is, null, null);
long time2 = System.currentTimeMillis();
logger.info("Parsed URI=[" + uri + "]: Parse elapsed: " + (time2 - time1) + " ms. Load elapsed: "
+ (time1 - time0) + " ms.");
this.showStyleSheet(styleSheet);
} catch (Exception err) {
logger.log(Level.ERROR, "Error trying to load URI=[" + uri + "].", err);
this.clearCssOutput();
}
}
/**
* Clear css output.
*/
private void clearCssOutput() {
this.cssOutput.clearDocument();
}
/**
* Show style sheet.
*
* @param styleSheet
* the style sheet
*/
private void showStyleSheet(CSSStyleSheet styleSheet) {
StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter);
writer.println("<DL>");
CSSRuleList ruleList = styleSheet.getCssRules();
int length = ruleList.getLength();
for (int i = 0; i < length; i++) {
CSSRule rule = ruleList.item(i);
writer.println("<DT><strong>Rule: type=" + rule.getType() + ",class=" + rule.getClass().getName()
+ "</strong></DT>");
writer.println("<DD>");
this.writeRuleInfo(writer, rule);
writer.println("</DD>");
}
writer.println("</DL>");
writer.flush();
String html = stringWriter.toString();
HtmlRendererContext rcontext = new SimpleHtmlRendererContext(this.cssOutput, (UserAgentContext) null);
this.cssOutput.setHtml(html, "about:css", rcontext);
}
/**
* Write rule info.
*
* @param writer
* the writer
* @param rule
* the rule
*/
private void writeRuleInfo(PrintWriter writer, CSSRule rule) {
if (rule instanceof CSSStyleRule) {
CSSStyleRule styleRule = (CSSStyleRule) rule;
writer.println("Selector: " + styleRule.getSelectorText());
writer.println("<br>");
writer.println("CSS Text: " + styleRule.getCssText());
} else if (rule instanceof CSSImportRule) {
CSSImportRule styleRule = (CSSImportRule) rule;
writer.println("HREF: " + styleRule.getHref());
writer.println("<br>");
writer.println("CSS Text: " + styleRule.getCssText());
}
}
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(String[] args) {
CssParserTest frame = new CssParserTest();
frame.setSize(800, 400);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
}