/* * Copyright 2013 LinkedIn Corp. All rights reserved * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.linkedin.databus2.ggParser.XmlStateMachine; import com.linkedin.databus2.core.DatabusException; import com.linkedin.databus2.schemas.SchemaRegistryService; import java.util.HashMap; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.apache.avro.Schema; import org.apache.log4j.Logger; public class XmlStreamReaderHelper { public final static String MODULE = XmlStreamReaderHelper.class.getName(); public final static Logger LOG = Logger.getLogger(MODULE); /** * Custom implementation of getElementText(). Reads all the text till the end of the element. * Should be called only for XMLStreamReader is in START_ELEMENT state. * * @param xmlStreamReader * @throws XMLStreamException */ public static String getTextChunkedReader(XMLStreamReader xmlStreamReader) throws XMLStreamException, DatabusException { if(xmlStreamReader.getEventType() != XMLStreamReader.START_ELEMENT) throw new DatabusException("The XmlStreamReader is not pointing to a start element"); StringBuffer sb = new StringBuffer(); while(xmlStreamReader.hasNext()) { int eventType = xmlStreamReader.next(); if(eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE) { sb.append(xmlStreamReader.getText()); } else if(eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT) { // skip LOG.error("Unknown state while processing characters (in method getText())"); } else if(eventType == XMLStreamConstants.END_DOCUMENT) { throw new DatabusException("Unexpected end of document when reading element text content"); } else if(eventType == XMLStreamConstants.START_ELEMENT) { throw new DatabusException("Element text content may not contain START_ELEMENT"); } else { throw new DatabusException("Unexpected event type "+eventType); } } return sb.toString(); } /** * Skip new lines after the end elements. * This function should be called when the cursor is pointing to CHARACTER and leaves the cursor * at END_ELEMENT OR START_ELEMENT * @param xmlStreamReader */ public static void skipNewLines(XMLStreamReader xmlStreamReader) throws XMLStreamException { if(xmlStreamReader.isCharacters()) { while(xmlStreamReader.isCharacters() && xmlStreamReader.hasNext()) xmlStreamReader.next(); } } public static void checkAndMoveNext(XMLStreamReader xmlStreamReader) throws DatabusException, XMLStreamException { if(xmlStreamReader.hasNext()) xmlStreamReader.next(); else throw new DatabusException("XmlStream does not have any more data"); } public static void checkAndMoveToNextTag(XMLStreamReader xmlStreamReader) throws DatabusException, XMLStreamException { if(xmlStreamReader.hasNext()) xmlStreamReader.nextTag(); else throw new DatabusException("XmlStream does not have any more data"); } /** * It moves the cursor to the next immediate tag set (next immediate ancestor or descendant) (START_ELEMENT OR END_ELEMENT). * Case 1: <start1>xxx</start1> <start2>yyy</start2> * Called anywhere from start1 tag set moves the cursor the <start2>'s START_ELEMENT * Case 2: <start2><start1>xxx</start1> </start2> * Called anywhere from start1 tag set moves the cursor the <start2>'s END_ELEMENT * Case 3:<start2><start1>xxx</start1> </start2> * Called from <start2> will set the cursor to the <start1> * Accepts both END_ELEMENT AND START_ELEMENT cursor states * @param xmlStreamReader * @throws DatabusException * @throws XMLStreamException */ @Deprecated public static void checkAndMoveToNextTagSet(XMLStreamReader xmlStreamReader) throws DatabusException, XMLStreamException { if(xmlStreamReader.isEndElement()) { if(xmlStreamReader.hasNext()) xmlStreamReader.nextTag(); else throw new DatabusException("XmlStream does not have any more data"); } else if(xmlStreamReader.isStartElement()) { XmlStreamReaderHelper.checkAndMoveNext(xmlStreamReader); if(xmlStreamReader.isCharacters()) { XmlStreamReaderHelper.checkAndMoveToNextTag(xmlStreamReader); } if(xmlStreamReader.isEndElement()) XmlStreamReaderHelper.checkAndMoveToNextTag(xmlStreamReader); if(!xmlStreamReader.isStartElement() && !xmlStreamReader.isEndElement()) throw new DatabusException("Inconsistent state, expected cursor state START_ELEMENT or END_ELEMENT"); } else throw new DatabusException("Unable to move to nextTag, expected START_ELEMENT or END_ELEMENT"); } public static HashMap<String, String> getAttributeMap(XMLStreamReader xmlStreamReader) { HashMap<String,String> attributeMap = new HashMap<String, String>(); int attributeCount = xmlStreamReader.getAttributeCount(); for(int i = 0; i < attributeCount; i++) { String attributeName = xmlStreamReader.getAttributeName(i).getLocalPart(); String attributeValue = xmlStreamReader.getAttributeValue(i); attributeMap.put(attributeName,attributeValue); } return attributeMap; } }