ohair@286: /* alanb@368: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.messaging.saaj.util; ohair@286: ohair@286: import java.io.*; ohair@286: ohair@286: import javax.xml.transform.TransformerException; ohair@286: ohair@286: /* ohair@286: * Class that parses the very first construct in the document i.e. ohair@286: * ohair@286: * ohair@286: * @author Panos Kougiouris (panos@acm.org) ohair@286: * @version ohair@286: */ ohair@286: ohair@286: public class XMLDeclarationParser { ohair@286: private String m_encoding; ohair@286: private PushbackReader m_pushbackReader; ohair@286: private boolean m_hasHeader; // preserve the case where no XML Header exists ohair@286: private String xmlDecl = null; ohair@286: static String gt16 = null; ohair@286: static String utf16Decl = null; ohair@286: static { ohair@286: try { ohair@286: gt16 = new String(">".getBytes("utf-16")); ohair@286: utf16Decl = new String("') { ohair@286: break; ohair@286: } ohair@286: } ohair@286: int len = index; ohair@286: ohair@286: String decl = xmlDeclStr.toString(); ohair@286: boolean utf16 = false; ohair@286: boolean utf8 = false; ohair@286: ohair@286: int xmlIndex = decl.indexOf(utf16Decl); ohair@286: if (xmlIndex > -1) { ohair@286: utf16 = true; ohair@286: } else { ohair@286: xmlIndex = decl.indexOf(" -1) { ohair@286: utf8 = true; ohair@286: } ohair@286: } ohair@286: ohair@286: // no XML decl ohair@286: if (!utf16 && !utf8) { ohair@286: m_pushbackReader.unread(aChar, 0, len); ohair@286: return; ohair@286: } ohair@286: m_hasHeader = true; ohair@286: ohair@286: if (utf16) { ohair@286: xmlDecl = new String(decl.getBytes(), "utf-16"); ohair@286: xmlDecl = xmlDecl.substring(xmlDecl.indexOf("<")); ohair@286: } else { ohair@286: xmlDecl = decl; ohair@286: } ohair@286: // do we want to check that there are no other characters preceeding encodingIndex) { ohair@286: throw new IOException("The 'version' attribute should preceed the 'encoding' attribute in an XML Declaration"); ohair@286: } ohair@286: ohair@286: int stdAloneIndex = xmlDecl.indexOf("standalone"); ohair@286: if ((stdAloneIndex > -1) && ((stdAloneIndex < versionIndex) || (stdAloneIndex < encodingIndex))) { ohair@286: throw new IOException("The 'standalone' attribute should be the last attribute in an XML Declaration"); ohair@286: } ohair@286: ohair@286: int eqIndex = xmlDecl.indexOf("=", encodingIndex); ohair@286: if (eqIndex == -1) { ohair@286: throw new IOException("Missing '=' character after 'encoding' in XML declaration"); ohair@286: } ohair@286: ohair@286: m_encoding = parseEncoding(xmlDecl, eqIndex); ohair@286: if(m_encoding.startsWith("\"")){ ohair@286: m_encoding = m_encoding.substring(m_encoding.indexOf("\"")+1, m_encoding.lastIndexOf("\"")); ohair@286: } else if(m_encoding.startsWith("\'")){ ohair@286: m_encoding = m_encoding.substring(m_encoding.indexOf("\'")+1, m_encoding.lastIndexOf("\'")); ohair@286: } ohair@286: } ohair@286: ohair@286: //-------------------------------------------------------------------- ohair@286: ohair@286: public void writeTo(Writer wr) throws IOException { ohair@286: if (!m_hasHeader) return; ohair@286: wr.write(xmlDecl.toString()); ohair@286: } ohair@286: ohair@286: private String parseEncoding(String xmlDeclFinal, int eqIndex) throws IOException { ohair@286: java.util.StringTokenizer strTok = new java.util.StringTokenizer( ohair@286: xmlDeclFinal.substring(eqIndex + 1)); ohair@286: if (strTok.hasMoreTokens()) { ohair@286: String encodingTok = strTok.nextToken(); ohair@286: int indexofQ = encodingTok.indexOf("?"); ohair@286: if (indexofQ > -1) { ohair@286: return encodingTok.substring(0,indexofQ); ohair@286: } else { ohair@286: return encodingTok; ohair@286: } ohair@286: } else { ohair@286: throw new IOException("Error parsing 'encoding' attribute in XML declaration"); ohair@286: } ohair@286: } ohair@286: ohair@286: }