001/** 002 * Copyright 2015 DuraSpace, Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.fcrepo.oai.jersey; 017 018import java.io.IOException; 019import java.io.InputStream; 020 021/** 022 * An {@link InputStream} implementation which strips the leading XML 023 * Declaration of a XML document If the xml document starts with 024 * {@code<?xml...?>}, the implementation will skip these bytes and start 025 * streaming directly after the XML declaration 026 * 027 * @author frank asseg 028 */ 029public class XmlDeclarationStrippingInputStream extends InputStream { 030 031 private final InputStream src; 032 033 private String firstElement; 034 035 private boolean checked = false; 036 037 private boolean hasDeclaration = false; 038 039 private int elementIndex; 040 041 /** 042 * Instantiates a new Xml declaration stripping input stream. 043 * 044 * @param src the src 045 */ 046 public XmlDeclarationStrippingInputStream(final InputStream src) { 047 super(); 048 this.src = src; 049 } 050 051 @Override 052 public int read() throws IOException { 053 if (!checked) { 054 checked = true; 055 final StringBuffer name = new StringBuffer(); 056 int b = src.read(); 057 if (b == -1) { 058 return -1; 059 } 060 while (Character.isWhitespace(b) || Character.isISOControl(b)) { 061 b = src.read(); 062 } 063 if ((char) b == '<') { 064 name.append((char) b); 065 while ((b = src.read()) != -1 && (char) b != '>') { 066 name.append((char) b); 067 } 068 name.append((char) b); 069 firstElement = name.toString(); 070 if (firstElement.toLowerCase().startsWith("<?xml ")) { 071 hasDeclaration = true; 072 b = src.read(); 073 while (Character.isWhitespace(b) || Character.isISOControl(b)) { 074 b = src.read(); 075 } 076 return b; 077 } 078 } 079 } 080 if (!hasDeclaration && elementIndex < firstElement.length()) { 081 return firstElement.charAt(elementIndex++); 082 } 083 return src.read(); 084 } 085 086}