/* * Copyright (C) 2000-2015 aw2.0 LTD * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD 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 OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbd.org/ * $Id: ValidationInputSource.java 2506 2015-02-08 22:25:59Z alan $ */ package com.naryx.tagfusion.cfm.xml.parse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import org.xml.sax.InputSource; /** * InputSource subclass that manipulates the <!DOCTYPE ...> element depending on * the value of mode. If mode == ADD_MODIFY, then, this will replace the * existing <!DOCTYPE ...> element with the same <!DOCTYPE ...> element, but * with a new SYSTEM identifier, CUSTOM_DTD. If mode == REMOVE_MODIFY, any * existing doctype declaration will be updated so that it has no SYSTEM/PUBLIC * identifier. If mode == REMOVE, the <!DOCTYPE ...> element is simply removed * from the document stream and parsing proceeds without it. If mode == * NO_CHANGE, no changes will be made. * */ public class ValidationInputSource extends InputSource { /** Internal SYSTEM identifier for our modified DTD declarations */ public static final String CUSTOM_DTD = DTDFilterReader.CUSTOM_DTD; /** * Using mode == READ_ADD, the existing doctype will be read. If no doctype * exists in the xml data, then one will be inserted that contains the * CUSTOM_DTD SYSTEM identifier. Using mode == REMOVE_MODIFY will result in * any existing doctype declaration being updated so that it has no * SYSTEM/PUBLIC identifier. Using mode == REMOVE will result in the <!DOCTYPE * ...> element simply being removed from the document stream. Using mode == * NO_CHANGE, no changes will be made. */ public static final byte READ_ADD = DTDFilterReader.READ_ADD; public static final byte REMOVE_MODIFY = DTDFilterReader.REMOVE_MODIFY; public static final byte REMOVE = DTDFilterReader.REMOVE; public static final byte NO_CHANGE = DTDFilterReader.NO_CHANGE; protected XmlSource xs = null; protected InputSource is = null; protected byte mode = READ_ADD; protected DTDFilterReader.DTDListener listener = null; /** * Default constructor. Wraps an InputSource from the specified XmlSource. If * mode == READ_ADD, then, this will read the existing <!DOCTYPE ...> element * or add a <!DOCTYPE ...> element with a new SYSTEM identifier and * CUSTOM_DTD. If mode == REMOVE_MODIFY, the any existing doctype declaration * will be updated to have its SYSTEM/PUBLIC identifier removed. If mode == * NO_CHANGE, no changes will be made. If mode == REMOVE, the entire <!DOCTYPE * ...> element is removed. * * @param xs * XmlSource from which we can get an InputSource to wrap * @param mode * either READ_ADD, REMOVE, REMOVE_MODIFY, or NO_CHANGE * @throws IOException */ public ValidationInputSource(XmlSource xs, byte mode) throws IOException { this(xs, null, mode); } /** * Default constructor. Wraps an InputSource from the specified XmlSource. If * mode == READ_ADD, then, this will read the existing <!DOCTYPE ...> element * or add a <!DOCTYPE ...> element with a new SYSTEM identifier and * CUSTOM_DTD. If mode == REMOVE_MODIFY, the any existing doctype declaration * will be updated to have its SYSTEM/PUBLIC identifier removed. If mode == * NO_CHANGE, no changes will be made. If mode == REMOVE, the entire <!DOCTYPE * ...> element is removed. * * @param xs * XmlSource from which we can get an InputSource to wrap * @param listener * DTDFilterReader.DTDListener listener for the existing DTD info * @param mode * either READ_ADD, REMOVE, REMOVE_MODIFY, or NO_CHANGE * @throws IOException */ public ValidationInputSource(XmlSource xs, DTDFilterReader.DTDListener listener, byte mode) throws IOException { this.xs = xs; this.is = xs.newInputSource(); this.mode = mode; this.listener = listener; } /** * Returns the public identifier for the underlying InputSource. * * @return public identifier for the underlying InputSource */ public String getPublicId() { return is.getPublicId(); } /** * Sets the public identifier for the underlying InputSource. * * @param publicId * public identifier for the underlying InputSource */ public void setPublicId(String publicId) { this.is.setPublicId(publicId); } /** * Returns the system identifier for the underlying InputSource. * * @return system identifier for the underlying InputSource */ public String getSystemId() { return is.getSystemId(); } /** * Sets the system identifier for the underlying InputSource. * * @param systemId * system identifier for the underlying InputSource */ public void setSystemId(String systemId) { is.setSystemId(systemId); } /** * Returns the encoding for the underlying InputSource. * * @return encoding for the underlying InputSource */ public String getEncoding() { return is.getEncoding(); } /** * Sets the encoding for the underyling InputSource. * * @param encoding * encoding for the underlying InputSource */ public void setEncoding(String encoding) { is.setEncoding(encoding); } /** * Returns a Reader for the character stream of the underlying InputSource, * filtered by our DTDFilter. * * @return filtered character stream */ public Reader getCharacterStream() { // Get our DTDFilterReader to do the handling Reader reader = is.getCharacterStream(); if (reader == null) { // Try as an InputStream InputStream input = null; String enc = null; try { enc = is.getEncoding(); input = is.getByteStream(); if (enc == null) { enc = XmlSource.getStreamEncoding(input); is = xs.newInputSource(); input = is.getByteStream(); } reader = new BufferedReader(new InputStreamReader(input, enc)); } catch (UnsupportedEncodingException ex) { throw new UnsupportedOperationException("Input data encoded in unsupported encoding. " + ex.getMessage()); } catch (IOException ex) { throw new UnsupportedOperationException("Could not read input data. " + ex.getMessage()); } } // Get our DTDFilterReader to do the handling DTDFilterReader rtn = new DTDFilterReader(reader, mode); if (this.listener != null) rtn.setListener(this.listener); return rtn; } /** * Sets the character stream for our underlying InputSource. This operation is * currently not supported and will throw an UnsupportedOperationException * when called. * * @param characterStream * replacement Reader for the underlying InputSource */ public void setCharacterStream(Reader characterStream) { throw new UnsupportedOperationException("Cannot set the character stream."); } /** * Returns an InputStream for the byte stream of the underlying InputSource, * filtered by our DTDFilter. * * @return filtered byte stream */ public InputStream getByteStream() { return null; } /** * Sets the byte stream for our underlying InputSource. This operation is * currently not supported and will throw an UnsupportedOperationException * when called. * * @param byteStream * replacement InputStream for the underlying InputSource */ public void setByteStream(InputStream byteStream) { throw new UnsupportedOperationException("Cannot set the byte stream."); } }