| /* |
| * Copyright 2001-2004 The Apache Software Foundation. |
| * |
| * 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 org.apache.axis.message; |
| |
| import org.apache.axis.encoding.DeserializationContext; |
| import org.xml.sax.ContentHandler; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.ext.LexicalHandler; |
| |
| /** |
| * This class records SAX2 Events and allows |
| * the events to be replayed by start and stop index |
| */ |
| public class SAX2EventRecorder { |
| |
| private static final Integer Z = new Integer(0); |
| |
| private static final Integer STATE_START_DOCUMENT = new Integer(1); |
| private static final Integer STATE_END_DOCUMENT = new Integer(2); |
| private static final Integer STATE_START_PREFIX_MAPPING = new Integer(3); |
| private static final Integer STATE_END_PREFIX_MAPPING = new Integer(4); |
| private static final Integer STATE_START_ELEMENT = new Integer(5); |
| private static final Integer STATE_END_ELEMENT = new Integer(6); |
| private static final Integer STATE_CHARACTERS = new Integer(7); |
| private static final Integer STATE_IGNORABLE_WHITESPACE = new Integer(8); |
| private static final Integer STATE_PROCESSING_INSTRUCTION = new Integer(9); |
| private static final Integer STATE_SKIPPED_ENTITY = new Integer(10); |
| |
| // This is a "custom" event which tells DeserializationContexts |
| // that the current element is moving down the stack... |
| private static final Integer STATE_NEWELEMENT = new Integer(11); |
| |
| // Lexical handler events... |
| private static final Integer STATE_START_DTD = new Integer(12); |
| private static final Integer STATE_END_DTD = new Integer(13); |
| private static final Integer STATE_START_ENTITY = new Integer(14); |
| private static final Integer STATE_END_ENTITY = new Integer(15); |
| private static final Integer STATE_START_CDATA = new Integer(16); |
| private static final Integer STATE_END_CDATA = new Integer(17); |
| private static final Integer STATE_COMMENT = new Integer(18); |
| |
| objArrayVector events = new objArrayVector(); |
| |
| public void clear() { |
| events = new objArrayVector(); |
| } |
| public int getLength() |
| { |
| return events.getLength(); |
| } |
| |
| public int startDocument() { |
| return events.add(STATE_START_DOCUMENT, Z,Z,Z,Z); |
| } |
| public int endDocument() { |
| return events.add(STATE_END_DOCUMENT, Z,Z,Z,Z); |
| } |
| public int startPrefixMapping(String p1, String p2) { |
| return events.add(STATE_START_PREFIX_MAPPING, p1, p2, Z,Z); |
| } |
| public int endPrefixMapping(String p1) { |
| return events.add(STATE_END_PREFIX_MAPPING, p1,Z,Z,Z); |
| } |
| public int startElement(String p1, String p2, String p3, org.xml.sax.Attributes p4) { |
| return events.add(STATE_START_ELEMENT, p1, p2, p3, p4); |
| } |
| public int endElement(String p1, String p2, String p3) { |
| return events.add(STATE_END_ELEMENT, p1, p2, p3, Z); |
| } |
| public int characters(char[] p1, int p2, int p3) { |
| return events.add(STATE_CHARACTERS, |
| (Object)clone(p1, p2, p3), |
| Z, Z, Z); |
| } |
| public int ignorableWhitespace(char[] p1, int p2, int p3) { |
| return events.add(STATE_IGNORABLE_WHITESPACE, |
| (Object)clone(p1, p2, p3), |
| Z, Z, Z); |
| } |
| public int processingInstruction(String p1, String p2) { |
| return events.add(STATE_PROCESSING_INSTRUCTION, p1, p2, Z,Z); |
| } |
| public int skippedEntity(String p1) { |
| return events.add(STATE_SKIPPED_ENTITY, p1, Z,Z,Z); |
| } |
| |
| public void startDTD(java.lang.String name, |
| java.lang.String publicId, |
| java.lang.String systemId) { |
| events.add(STATE_START_DTD, name, publicId, systemId, Z); |
| } |
| public void endDTD() { |
| events.add(STATE_END_DTD, Z, Z, Z, Z); |
| } |
| public void startEntity(java.lang.String name) { |
| events.add(STATE_START_ENTITY, name, Z, Z, Z); |
| } |
| public void endEntity(java.lang.String name) { |
| events.add(STATE_END_ENTITY, name, Z, Z, Z); |
| } |
| public void startCDATA() { |
| events.add(STATE_START_CDATA, Z, Z, Z, Z); |
| } |
| public void endCDATA() { |
| events.add(STATE_END_CDATA, Z, Z, Z, Z); |
| } |
| public void comment(char[] ch, |
| int start, |
| int length) { |
| events.add(STATE_COMMENT, |
| (Object)clone(ch, start, length), |
| Z, Z, Z); |
| } |
| |
| public int newElement(MessageElement elem) { |
| return events.add(STATE_NEWELEMENT, elem, Z,Z,Z); |
| } |
| |
| public void replay(ContentHandler handler) throws SAXException { |
| if (events.getLength() > 0) { |
| replay(0, events.getLength() - 1, handler); |
| } |
| } |
| |
| public void replay(int start, int stop, ContentHandler handler) throws SAXException { |
| // Special case : play the whole thing for [0, -1] |
| if ((start == 0) && (stop == -1)) { |
| replay(handler); |
| return; |
| } |
| |
| if (stop + 1 > events.getLength() || |
| stop < start) { |
| return; // should throw an error here |
| } |
| |
| LexicalHandler lexicalHandler = null; |
| if (handler instanceof LexicalHandler) { |
| lexicalHandler = (LexicalHandler) handler; |
| } |
| |
| for (int n = start; n <= stop; n++) { |
| Object event = events.get(n,0); |
| if (event == STATE_START_ELEMENT) { |
| handler.startElement((String)events.get(n,1), |
| (String)events.get(n,2), |
| (String)events.get(n,3), |
| (org.xml.sax.Attributes)events.get(n,4)); |
| |
| } else if (event == STATE_END_ELEMENT) { |
| handler.endElement((String)events.get(n,1), |
| (String)events.get(n,2), |
| (String)events.get(n,3)); |
| |
| } else if (event == STATE_CHARACTERS) { |
| char[] data = (char[])events.get(n,1); |
| handler.characters(data, 0, data.length); |
| |
| } else if (event == STATE_IGNORABLE_WHITESPACE) { |
| char[] data = (char[])events.get(n,1); |
| handler.ignorableWhitespace(data, 0, data.length); |
| |
| } else if (event == STATE_PROCESSING_INSTRUCTION) { |
| handler.processingInstruction((String)events.get(n,1), |
| (String)events.get(n,2)); |
| |
| } else if (event == STATE_SKIPPED_ENTITY) { |
| handler.skippedEntity((String)events.get(n,1)); |
| |
| } else if (event == STATE_START_DOCUMENT) { |
| handler.startDocument(); |
| |
| } else if (event == STATE_END_DOCUMENT) { |
| handler.endDocument(); |
| |
| } else if (event == STATE_START_PREFIX_MAPPING) { |
| handler.startPrefixMapping((String)events.get(n, 1), |
| (String)events.get(n, 2)); |
| |
| } else if (event == STATE_END_PREFIX_MAPPING) { |
| handler.endPrefixMapping((String)events.get(n, 1)); |
| |
| } else if (event == STATE_START_DTD && lexicalHandler != null) { |
| lexicalHandler.startDTD((String)events.get(n,1), |
| (String)events.get(n,2), |
| (String)events.get(n,3)); |
| } else if (event == STATE_END_DTD && lexicalHandler != null) { |
| lexicalHandler.endDTD(); |
| |
| } else if (event == STATE_START_ENTITY && lexicalHandler != null) { |
| lexicalHandler.startEntity((String)events.get(n,1)); |
| |
| } else if (event == STATE_END_ENTITY && lexicalHandler != null) { |
| lexicalHandler.endEntity((String)events.get(n,1)); |
| |
| } else if (event == STATE_START_CDATA && lexicalHandler != null) { |
| lexicalHandler.startCDATA(); |
| |
| } else if (event == STATE_END_CDATA && lexicalHandler != null) { |
| lexicalHandler.endCDATA(); |
| |
| } else if (event == STATE_COMMENT && lexicalHandler != null) { |
| char[] data = (char[])events.get(n,1); |
| lexicalHandler.comment(data, 0, data.length); |
| |
| } else if (event == STATE_NEWELEMENT) { |
| if (handler instanceof DeserializationContext) { |
| DeserializationContext context = |
| (DeserializationContext)handler; |
| context.setCurElement( |
| (MessageElement)(events.get(n,1))); |
| } |
| } |
| } |
| } |
| |
| private static char[] clone(char[] in, int off, int len) { |
| char[] out = new char[len]; |
| System.arraycopy(in, off, out, 0, len); |
| return out; |
| } |
| |
| ///////////////////////////////////////////// |
| class objArrayVector { |
| private int RECORD_SIZE = 5; |
| private int currentSize = 0; |
| private Object[] objarray = new Object[50 * RECORD_SIZE]; // default to 50 5 field records |
| |
| public int add(Object p1, Object p2, Object p3, Object p4, Object p5) { |
| if (currentSize == objarray.length) { |
| Object[] newarray = new Object[currentSize * 2]; |
| System.arraycopy(objarray, 0, newarray, 0, currentSize); |
| objarray = newarray; |
| } |
| int pos = currentSize / RECORD_SIZE; |
| objarray[currentSize++] = p1; |
| objarray[currentSize++] = p2; |
| objarray[currentSize++] = p3; |
| objarray[currentSize++] = p4; |
| objarray[currentSize++] = p5; |
| return pos; |
| } |
| |
| public Object get(int pos, int fld) { |
| return objarray[(pos * RECORD_SIZE) + fld]; |
| } |
| |
| public int getLength() { |
| return (currentSize / RECORD_SIZE); |
| } |
| } |
| ///////////////////////////////////////////// |
| |
| } |