| /* |
| * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code 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 |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package build.tools.dtdbuilder; |
| |
| import javax.swing.text.html.parser.*; |
| import java.io.IOException; |
| import java.io.FileInputStream; |
| import java.io.InputStream; |
| import java.io.Reader; |
| import java.io.InputStreamReader; |
| import java.io.CharArrayReader; |
| import java.io.FilterReader; |
| import java.util.Stack; |
| import java.net.URL; |
| |
| /** |
| * A stream for reading HTML files. This stream takes care |
| * of \r\n conversions and parameter entity expansion. |
| * |
| * @see DTD |
| * @see DTDParser |
| * @author Arthur van Hoff |
| * @author Steven B. Byrne |
| */ |
| public final |
| class DTDInputStream extends FilterReader implements DTDConstants { |
| public DTD dtd; |
| public Stack<Object> stack = new Stack<>(); |
| public char str[] = new char[64]; |
| public int replace = 0; |
| public int ln = 1; |
| public int ch; |
| |
| /** |
| * Create the stream. |
| */ |
| public DTDInputStream(InputStream in, DTD dtd) throws IOException { |
| super(new InputStreamReader(in)); |
| this.dtd = dtd; |
| this.ch = in.read(); |
| } |
| |
| /** |
| * Error |
| */ |
| public void error(String msg) { |
| System.out.println("line " + ln + ": dtd input error: " + msg); |
| } |
| |
| /** |
| * Push a single character |
| */ |
| public void push(int ch) throws IOException { |
| char data[] = {(char)ch}; |
| push(new CharArrayReader(data)); |
| } |
| |
| |
| /** |
| * Push an array of bytes. |
| */ |
| public void push(char data[]) throws IOException { |
| if (data.length > 0) { |
| push(new CharArrayReader(data)); |
| } |
| } |
| |
| /** |
| * Push an entire input stream |
| */ |
| void push(Reader in) throws IOException { |
| stack.push(new Integer(ln)); |
| stack.push(new Integer(ch)); |
| stack.push(this.in); |
| this.in = in; |
| ch = in.read(); |
| } |
| |
| /** |
| * Read a character from the input. Automatically pop |
| * a stream of the stack if the EOF is reached. Also replaces |
| * parameter entities. |
| * [60] 350:22 |
| */ |
| @SuppressWarnings("fallthrough") |
| public int read() throws IOException { |
| switch (ch) { |
| case '%': { |
| ch = in.read(); |
| if (replace > 0) { |
| return '%'; |
| } |
| |
| int pos = 0; |
| while (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || |
| ((ch >= '0') && (ch <= '9')) || (ch == '.') || (ch == '-')) { |
| str[pos++] = (char)ch; |
| ch = in.read(); |
| } |
| if (pos == 0) { |
| return '%'; |
| } |
| |
| String nm = new String(str, 0, pos); |
| Entity ent = dtd.getEntity(nm); |
| if (ent == null) { |
| error("undefined entity reference: " + nm); |
| return read(); |
| } |
| |
| // Skip ; or RE |
| switch (ch) { |
| case '\r': |
| ln++; |
| /* fall through */ |
| case ';': |
| ch = in.read(); |
| break; |
| case '\n': |
| ln++; |
| if ((ch = in.read()) == '\r') { |
| ch = in.read(); |
| } |
| break; |
| } |
| |
| // Push the entity. |
| try { |
| push(getEntityInputReader(ent)); |
| } catch (Exception e) { |
| error("entity data not found: " + ent + ", " + ent.getString()); |
| } |
| return read(); |
| } |
| |
| case '\n': |
| ln++; |
| if ((ch = in.read()) == '\r') { |
| ch = in.read(); |
| } |
| return '\n'; |
| |
| case '\r': |
| ln++; |
| ch = in.read(); |
| return '\n'; |
| |
| case -1: |
| if (stack.size() > 0) { |
| in = (Reader)stack.pop(); |
| ch = ((Integer)stack.pop()).intValue(); |
| ln = ((Integer)stack.pop()).intValue(); |
| return read(); |
| } |
| return -1; |
| |
| default: |
| int c = ch; |
| ch = in.read(); |
| return c; |
| } |
| } |
| |
| /** |
| * Return the data as a stream. |
| */ |
| private Reader getEntityInputReader(Entity ent) throws IOException { |
| if ((ent.type & Entity.PUBLIC) != 0) { |
| // InputStream is = DTDBuilder.mapping.get(ent.getString()).openStream(); |
| // return new InputStreamReader(is); |
| String path = DTDBuilder.mapping.get(ent.getString()); |
| |
| return new InputStreamReader(new FileInputStream(path)); |
| } |
| if ((ent.type & Entity.SYSTEM) != 0) { |
| //InputStream is = new URL(DTDBuilder.mapping.base, ent.getString()).openStream(); |
| String path = DTDBuilder.mapping.baseStr + ent.getString(); |
| return new InputStreamReader(new FileInputStream(path)); |
| } |
| return new CharArrayReader(ent.data); |
| } |
| |
| } |