All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.webcohesion.ofx4j.io.OFXV2ContentHandler Maven / Gradle / Ivy

Go to download

OFX4J is a Java implementation of Open Financial Exchange, which defines web service APIs for interfacing with financial institutions.

The newest version!
/*
 * Copyright 2008 Web Cohesion
 *
 * 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.webcohesion.ofx4j.io;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * @author Ryan Heaton
 */
public class OFXV2ContentHandler extends org.xml.sax.helpers.DefaultHandler {

  private static final Log LOG = LogFactory.getLog(OFXV2ContentHandler.class);

  private final Stack eventStack = new Stack();
  private final OFXHandler ofxHandler;
  private final List startedEvents = new ArrayList();

  public OFXV2ContentHandler(OFXHandler ofxHandler) {
    if (ofxHandler == null) {
      throw new IllegalArgumentException("An OFX handler must be supplied.");
    }

    this.ofxHandler = ofxHandler;
  }

  @Override
  public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("START ELEMENT: " + qName);
    }

    if ((!eventStack.isEmpty()) && (eventStack.peek().getEventType() == OFXParseEvent.Type.ELEMENT) && (!isAlreadyStarted(eventStack.peek()))) {
      String eventValue = eventStack.peek().getEventValue();
      if (LOG.isDebugEnabled()) {
        LOG.debug("Element " + qName + " is starting aggregate " + eventValue);
      }

      //the last element started was not ended; we are assuming we've started a new aggregate.
      try {
        this.ofxHandler.startAggregate(eventValue);
      }
      catch (OFXParseException e) {
        throw new SAXException(e);
      }

      this.startedEvents.add(eventStack.peek());
    }

    eventStack.push(new OFXParseEvent(OFXParseEvent.Type.ELEMENT, qName));
  }

  /**
   * Whether the specified element aggregate has already been started.
   *
   * @param event The event containing the start.
   * @return Whether the specified element aggregate has already been started.
   */
  protected boolean isAlreadyStarted(OFXParseEvent event) {
    return this.startedEvents.contains(event);
  }

  @Override
  public void endElement(String uri, String localName, String qName) throws SAXException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("END ELEMENT: " + qName);
    }

    OFXParseEvent eventToFinish = eventStack.pop();
    if (eventToFinish.getEventType() == OFXParseEvent.Type.CHARACTERS) {
      String chars = eventToFinish.getEventValue().trim();

      if (eventStack.isEmpty()) {
        throw new IllegalStateException("Illegal character data outside main OFX root element: \"" + chars + "\".");
      }
      else {
        OFXParseEvent elementEvent = eventStack.pop();
        if (elementEvent.getEventType() != OFXParseEvent.Type.ELEMENT) {
          throw new IllegalStateException("Illegal OFX event before characters \"" + chars + "\" (" + elementEvent.getEventType() + ")!");
        }
        else {
          String value = elementEvent.getEventValue();
          if (LOG.isDebugEnabled()) {
            LOG.debug("Element " + value + " processed with value " + chars);
          }
          try {
            this.ofxHandler.onElement(value, chars);
          }
          catch (OFXParseException e) {
            throw new SAXException(e);
          }
        }
      }
    }
    else if (eventToFinish.getEventType() == OFXParseEvent.Type.ELEMENT) {
      //we're ending an aggregate (no character data on the stack).
      if (qName.equals(eventToFinish.getEventValue())) {
        //the last element on the stack is ours; we're ending an OFX aggregate.
        String value = eventToFinish.getEventValue();
        if (LOG.isDebugEnabled()) {
          LOG.debug("Ending aggregate " + value);
        }
        try {
          this.ofxHandler.endAggregate(value);
        }
        catch (OFXParseException e) {
          throw new SAXException(e);
        }

        this.startedEvents.remove(eventToFinish);
      }
      else {
        throw new IllegalStateException("Unexpected end tag: " + eventToFinish.getEventValue());
      }
    }
    else {
      throw new IllegalStateException("Illegal OFX event: " + eventToFinish.getEventType());
    }
  }

  @Override
  public void characters(char ch[], int start, int length) throws SAXException {
    String value = new String(ch, start, length);
    if (value.trim().length() > 0) {
      OFXParseEvent event;
      if ((!eventStack.isEmpty()) && (eventStack.peek().getEventType() == OFXParseEvent.Type.CHARACTERS)) {
        //append the characters...
        event = new OFXParseEvent(OFXParseEvent.Type.CHARACTERS, eventStack.pop().getEventValue() + value);
      }
      else {
        event = new OFXParseEvent(OFXParseEvent.Type.CHARACTERS, value);
      }
      eventStack.push(event);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy