5126N/A/*
5126N/A * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
5126N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5126N/A *
5126N/A * This code is free software; you can redistribute it and/or modify it
5126N/A * under the terms of the GNU General Public License version 2 only, as
5126N/A * published by the Free Software Foundation.
5126N/A *
5126N/A * This code is distributed in the hope that it will be useful, but WITHOUT
5126N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5126N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5126N/A * version 2 for more details (a copy is included in the LICENSE file that
5126N/A * accompanied this code).
5126N/A *
5126N/A * You should have received a copy of the GNU General Public License version
5126N/A * 2 along with this work; if not, write to the Free Software Foundation,
5126N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5126N/A *
5126N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5126N/A * or visit www.oracle.com if you need additional information or have any
5126N/A * questions.
5126N/A */
5126N/A
5126N/A/* @test
5126N/A @bug 7165725
5126N/A @summary Tests if HTML parser can handle successive script tags in a line
5126N/A and it does not call false text callback after script tags.
5126N/A @run main bug7165725
5126N/A*/
5126N/A
5126N/Aimport sun.awt.SunToolkit;
5126N/A
5126N/Aimport java.awt.BorderLayout;
5126N/Aimport java.io.File;
5126N/Aimport java.io.FileReader;
5126N/Aimport java.io.IOException;
5126N/Aimport java.net.URL;
5126N/Aimport java.util.ArrayList;
5126N/Aimport java.util.Arrays;
5126N/Aimport java.util.List;
5126N/Aimport javax.swing.*;
5126N/Aimport javax.swing.text.AbstractDocument.AbstractElement;
5126N/Aimport javax.swing.text.AbstractDocument;
5126N/Aimport javax.swing.text.Document;
5126N/Aimport javax.swing.text.MutableAttributeSet;
5126N/Aimport javax.swing.text.html.HTML;
5126N/Aimport javax.swing.text.html.HTMLDocument;
5126N/Aimport javax.swing.text.html.HTMLEditorKit;
5126N/Aimport javax.swing.text.html.parser.ParserDelegator;
5126N/A
5126N/Apublic class bug7165725 extends JFrame {
5126N/A private static class GoldenElement {
5126N/A
5126N/A private String goldenName;
5126N/A private List<GoldenElement> goldenChildren;
5126N/A
5126N/A GoldenElement(String goldenName, GoldenElement... goldenChildren){
5126N/A this.goldenName = goldenName;
5126N/A if (goldenChildren != null) {
5126N/A this.goldenChildren = Arrays.asList(goldenChildren);
5126N/A } else {
5126N/A this.goldenChildren = new ArrayList<>();
5126N/A }
5126N/A }
5126N/A
5126N/A // throws RuntimeException if not ok
5126N/A public void checkStructureEquivalence(AbstractDocument.AbstractElement elem) {
5126N/A String name = elem.getName();
5126N/A if (!goldenName.equals(name)) {
5126N/A throw new RuntimeException("Bad structure: expected element name is '" + goldenName + "' but the actual name was '" + name + "'.");
5126N/A }
5126N/A int goldenChildCount = goldenChildren.size();
5126N/A int childCount = elem.getChildCount();
5126N/A if (childCount != goldenChildCount) {
5126N/A System.out.print("D: children: ");
5126N/A for (int i = 0; i < childCount; i++) {
5126N/A System.out.print(" " + elem.getElement(i).getName());
5126N/A }
5126N/A System.out.println("");
5126N/A System.out.print("D: goldenChildren: ");
5126N/A for (GoldenElement ge : goldenChildren) {
5126N/A System.out.print(" " + ge.goldenName);
5126N/A }
5126N/A System.out.println("");
5126N/A
5126N/A throw new RuntimeException("Bad structure: expected child count of element '" + goldenName + "' is '" + goldenChildCount + "' but the actual count was '" + childCount + "'.");
5126N/A }
5126N/A for (int i = 0; i < childCount; i++) {
5126N/A AbstractDocument.AbstractElement nextElem = (AbstractDocument.AbstractElement) elem.getElement(i);
5126N/A GoldenElement goldenElement = goldenChildren.get(i);
5126N/A goldenElement.checkStructureEquivalence(nextElem);
5126N/A }
5126N/A }
5126N/A }
5126N/A
5126N/A private JEditorPane editorPane;
5126N/A public void execute(final String urlStr, final GoldenElement goldenElement) throws Exception {
5126N/A System.out.println();
5126N/A System.out.println("***** TEST: " + urlStr + " *****");
5126N/A System.out.println();
5126N/A
5126N/A SwingUtilities.invokeAndWait(new Runnable() {
5126N/A public void run() {
5126N/A try {
5126N/A editorPane = new JEditorPane();
5126N/A editorPane.setEditorKit(new HTMLEditorKit() {
5126N/A public Document createDefaultDocument() {
5126N/A AbstractDocument doc =
5126N/A (AbstractDocument) super.createDefaultDocument();
5126N/A doc.setAsynchronousLoadPriority(-1);
5126N/A return doc;
5126N/A }
5126N/A });
5126N/A editorPane.setPage(new URL(urlStr));
5126N/A } catch (IOException ex) {
5126N/A throw new RuntimeException("Test failed", ex);
5126N/A }
5126N/A editorPane.setEditable(false);
5126N/A JScrollPane scroller = new JScrollPane();
5126N/A JViewport vp = scroller.getViewport();
5126N/A vp.add(editorPane);
5126N/A add(scroller, BorderLayout.CENTER);
5126N/A setDefaultCloseOperation(EXIT_ON_CLOSE);
5126N/A setSize(400, 400);
5126N/A setLocationRelativeTo(null);
5126N/A setVisible(true);
5126N/A }
5126N/A });
5126N/A
5126N/A ((SunToolkit) SunToolkit.getDefaultToolkit()).realSync();
5126N/A
5126N/A SwingUtilities.invokeAndWait(new Runnable() {
5126N/A public void run() {
5126N/A HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
5126N/A doc.dump(System.out);
5126N/A goldenElement.checkStructureEquivalence((AbstractElement) doc.getDefaultRootElement());
5126N/A dispose();
5126N/A }
5126N/A });
5126N/A
5126N/A System.out.println();
5126N/A System.out.println("*********************************");
5126N/A System.out.println();
5126N/A }
5126N/A
5126N/A public static void main(String[] args) throws Exception {
5126N/A
5126N/A String dirURL = getDirURL();
5126N/A
5126N/A System.out.println("dirURL = " + dirURL);
5126N/A
5126N/A new bug7165725().execute(dirURL + "successive-script-tag.html", createSuccessiveScriptTags());
5126N/A new bug7165725().execute(dirURL + "false-text-after-script.html", createFalseTextAfterScript());
5126N/A
5126N/A checkByCallbackForSuccessiveScript();
5126N/A checkByCallbackForFalseTextAfterScript();
5126N/A
5126N/A System.out.println();
5126N/A System.out.println();
5126N/A System.out.println("Test passed.");
5126N/A }
5126N/A
5126N/A static String getDirURL() {
5126N/A return "file:///" +
5126N/A new File(System.getProperty("test.src", ".")).getAbsolutePath() +
5126N/A File.separator;
5126N/A }
5126N/A
5126N/A static String getParsedContentOneLine(String path) throws Exception {
5126N/A File f = new File(path);
5126N/A FileReader fr = new FileReader(f);
5126N/A ParserDelegator pd = new ParserDelegator();
5126N/A SBParserCallback sbcallback = new SBParserCallback();
5126N/A pd.parse(fr, sbcallback, true);
5126N/A fr.close();
5126N/A return sbcallback.getStringOneLine();
5126N/A }
5126N/A
5126N/A static String getParsedContentOneLine(URL url) throws Exception {
5126N/A return getParsedContentOneLine(url.getPath());
5126N/A }
5126N/A
5126N/A static void checkByCallbackForSuccessiveScript() throws Exception {
5126N/A String content = getParsedContentOneLine(new URL(getDirURL() + "successive-script-tag.html"));
5126N/A if (!content.matches(".*<script .*/js/js1\\.js.*<script .*/js/js2\\.js.*<script .*/js/js3\\.js.*"))
5126N/A throw new RuntimeException("Failed to lookup script tags/attributes.");
5126N/A if (!content.matches(".*<style .*stylesheets/base\\.css.*<style .*stylesheets/adv\\.css.*"))
5126N/A throw new RuntimeException("Failed to lookup style tags.");
5126N/A }
5126N/A
5126N/A static void checkByCallbackForFalseTextAfterScript() throws Exception {
5126N/A String content = getParsedContentOneLine(new URL(getDirURL() + "false-text-after-script.html"));
5126N/A final int bodyIdx = content.indexOf("<body ");
5126N/A if (bodyIdx > 0) {
5126N/A String sbody = content.substring(bodyIdx);
5126N/A // There should be no Text(...) in this html
5126N/A if (sbody.indexOf("Text(") >= 0)
5126N/A throw new RuntimeException("Unexpected text found.");
5126N/A } else {
5126N/A throw new RuntimeException("Failed to find body tag.");
5126N/A }
5126N/A }
5126N/A
5126N/A private static GoldenElement createSuccessiveScriptTags() {
5126N/A return new GoldenElement("html",
5126N/A new GoldenElement("head",
5126N/A new GoldenElement("p-implied",
5126N/A new GoldenElement("title"),
5126N/A new GoldenElement("title"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("comment"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("comment"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("comment"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("content"))),
5126N/A new GoldenElement("body",
5126N/A new GoldenElement("p-implied",
5126N/A new GoldenElement("content"))));
5126N/A }
5126N/A
5126N/A private static GoldenElement createFalseTextAfterScript() {
5126N/A return new GoldenElement("html",
5126N/A new GoldenElement("head",
5126N/A new GoldenElement("p-implied",
5126N/A new GoldenElement("title"),
5126N/A new GoldenElement("title"),
5126N/A new GoldenElement("content"))),
5126N/A new GoldenElement("body",
5126N/A new GoldenElement("form",
5126N/A new GoldenElement("p-implied",
5126N/A new GoldenElement("input"),
5126N/A new GoldenElement("input"),
5126N/A new GoldenElement("content"))),
5126N/A new GoldenElement("p-implied",
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("comment"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("comment"),
5126N/A new GoldenElement("script"),
5126N/A new GoldenElement("content"))));
5126N/A }
5126N/A
5126N/A static class SBParserCallback extends HTMLEditorKit.ParserCallback
5126N/A {
5126N/A private int indentSize = 0;
5126N/A private ArrayList<String> elist = new ArrayList<>();
5126N/A
5126N/A public String getStringOneLine() {
5126N/A StringBuilder sb = new StringBuilder();
5126N/A for (String s : elist) sb.append(s);
5126N/A return sb.toString();
5126N/A }
5126N/A
5126N/A public String toString() {
5126N/A StringBuffer sb = new StringBuffer();
5126N/A for (String s : elist) sb.append(s + "\n");
5126N/A return sb.toString();
5126N/A }
5126N/A
5126N/A protected void indent() {
5126N/A indentSize += 3;
5126N/A }
5126N/A protected void unIndent() {
5126N/A indentSize -= 3; if (indentSize < 0) indentSize = 0;
5126N/A }
5126N/A
5126N/A protected String pIndent() {
5126N/A StringBuilder sb = new StringBuilder();
5126N/A for(int i = 0; i < indentSize; i++) sb.append(" ");
5126N/A return sb.toString();
5126N/A }
5126N/A
5126N/A public void handleText(char[] data, int pos) {
5126N/A elist.add(pIndent() + "Text(" + data.length + " chars) \"" + new String(data) + "\"");
5126N/A }
5126N/A
5126N/A public void handleComment(char[] data, int pos) {
5126N/A elist.add(pIndent() + "Comment(" + data.length + " chars)");
5126N/A }
5126N/A
5126N/A public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
5126N/A elist.add(pIndent() + "Tag start(<" + t.toString() + " " + a + ">, " +
5126N/A a.getAttributeCount() + " attrs)");
5126N/A indent();
5126N/A }
5126N/A
5126N/A public void handleEndTag(HTML.Tag t, int pos) {
5126N/A unIndent();
5126N/A elist.add(pIndent() + "Tag end(</" + t.toString() + ">)");
5126N/A }
5126N/A
5126N/A public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
5126N/A elist.add(pIndent() + "Tag(<" + t.toString() + ">, " +
5126N/A a.getAttributeCount() + " attrs)");
5126N/A }
5126N/A
5126N/A public void handleError(String errorMsg, int pos){
5126N/A }
5126N/A }
5126N/A}