Package org.apache.abdera.parser.stax

Source Code of org.apache.abdera.parser.stax.FOMBuilder

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  The ASF licenses this file to You
* 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.  For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.abdera.parser.stax;

import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.abdera.factory.Factory;
import org.apache.abdera.filter.ParseFilter;
import org.apache.abdera.filter.TextFilter;
import org.apache.abdera.model.Content;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Element;
import org.apache.abdera.model.Text;
import org.apache.abdera.parser.ParserOptions;
import org.apache.abdera.util.Constants;
import org.apache.axiom.om.OMConstants;
import org.apache.axiom.om.OMContainer;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMText;
import org.apache.axiom.om.impl.OMContainerEx;
import org.apache.axiom.om.impl.OMNodeEx;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.util.OMSerializerUtil;


public class FOMBuilder
  extends StAXOMBuilder
  implements Constants {

  private FOMFactory fomfactory = null;
  private Document fomDocument = null;
  private ParserOptions parserOptions = null;
  private int depth = 0;
  private int depthInSkipElement = 0;
 
  public FOMBuilder(
    FOMFactory factory,
    XMLStreamReader parser,
    ParserOptions parserOptions) {
      super(factory, parser);
      document = (OMDocument) factory.newDocument();
      this.parserOptions = parserOptions;
      fomfactory = factory;
  }

  public FOMBuilder(
    FOMFactory factory,
    XMLStreamReader parser) {
      super(factory, parser);
      document = (OMDocument) factory.newDocument();
      fomfactory = factory;
  }
 
  public FOMBuilder(
    String filePath,
    ParserOptions parserOptions)
      throws XMLStreamException,
             FileNotFoundException {
    super(filePath);
    document = (OMDocument) Factory.INSTANCE.newDocument();
    this.parserOptions = parserOptions;
    fomfactory = getFomFactory();
    setOMBuilderFactory(fomfactory);
  }

  public FOMBuilder(
    FOMFactory factory,
    String filePath,
    ParserOptions parserOptions)
      throws XMLStreamException,
             FileNotFoundException {
    super(filePath);
    document = (OMDocument) factory.newDocument();
    this.parserOptions = parserOptions;
    fomfactory = factory;
    setOMBuilderFactory(fomfactory);
  }
 
  public FOMBuilder(
    InputStream inStream,
    ParserOptions parserOptions)
      throws XMLStreamException {
    super(inStream);
    document = (OMDocument) Factory.INSTANCE.newDocument();
    this.parserOptions = parserOptions;
    fomfactory = getFomFactory();
    setOMBuilderFactory(fomfactory);
  }

  public FOMBuilder(
    FOMFactory factory,
    InputStream inStream,
    ParserOptions parserOptions)
      throws XMLStreamException {
    super(inStream);
    document = (OMDocument) factory.newDocument();
    this.parserOptions = parserOptions;
    fomfactory = factory;
    setOMBuilderFactory(fomfactory);
  }

  public FOMBuilder(
    XMLStreamReader parser,
    ParserOptions parserOptions) {
      super(parser);
      document = (OMDocument) Factory.INSTANCE.newDocument();
      this.parserOptions = parserOptions;
      fomfactory = getFomFactory();
      setOMBuilderFactory(fomfactory);
  }
 
  public FOMBuilder(
    XMLStreamReader parser,
    FOMFactory factory,
    ParserOptions parserOptions) {
      super(factory, parser);
      document = (OMDocument) factory.newDocument();
      this.parserOptions = parserOptions;
      fomfactory = factory;
  }
  private FOMFactory getFomFactory() {
    FOMFactory factory =
      (parserOptions != null && parserOptions.getFactory() != null) ?
      (FOMFactory)parserOptions.getFactory() : null;
    if (factory == null)
      factory = (Factory.INSTANCE instanceof FOMFactory) ?
          (FOMFactory)Factory.INSTANCE : new FOMFactory();
    return factory;
  }
 
  public ParserOptions getParserOptions() {
    return parserOptions;
  }
 
  @Override
  protected OMNode createOMElement() throws OMException {
    depth++;
    OMElement node;
    String elementName = parser.getLocalName();
    if (lastNode == null) {
        node = constructNode(null, elementName);
    } else if (lastNode.isComplete()) {
        node =
          constructNode(
            (OMContainer) lastNode.getParent(),
            elementName);
        if (node != null) {
          ((OMNodeEx) lastNode).setNextOMSibling(node);
          ((OMNodeEx) node).setPreviousOMSibling(lastNode);
        }
    } else {
        OMElement e = (OMElement) lastNode;
        node = constructNode((OMElement) lastNode, elementName);
        e.setFirstChild(node);
    }
    return node;
  }

  protected Text.Type getTextType() {
    Text.Type ttype = Text.Type.TEXT;
    String type = parser.getAttributeValue(null, LN_TYPE);
    if (type != null) {
      ttype = Text.Type.typeFromString(type);
      if (ttype == null)
        throw new FOMUnsupportedTextTypeException(type);
    }
    return ttype;
  }
 
  protected Content.Type getContentType() {
    Content.Type ctype = Content.Type.TEXT;
    String type = parser.getAttributeValue(null, LN_TYPE);
    String src = parser.getAttributeValue(null, LN_SRC);
    if (type != null) {
      ctype = Content.Type.typeFromString(type);
      if (ctype == null)
        throw new FOMUnsupportedContentTypeException(type);
    } else if (type == null && src != null) {
      ctype = Content.Type.MEDIA;
    }
    return ctype;
  }
 
  private boolean isAcceptableToParse(QName qname, boolean attribute) {
    if (parserOptions == null) return true;
    ParseFilter filter = parserOptions.getParseFilter();
    return (filter != null) ?
      (!attribute) ?
         filter.acceptable(qname) :
         filter.acceptableAttribute(parser.getName(), qname):
      true;
  }
 
  private OMNode applyTextFilter(int type) {
    if (parserOptions != null) {
      if (parser.isWhiteSpace() && parserOptions.getIgnoreWhitespace()) return createOMText("",type);
      TextFilter filter = parserOptions.getTextFilter();
      if (filter != null) {
        String value = parser.getText();
        if (!lastNode.isComplete())
          value = filter.filterText(value, (Element)lastNode);
        return createOMText(value, type);
      }
    }
    return createOMText(type);
  }
 
  private String applyAttributeTextFilter(String value, QName attribute, Element parent) {
    if (parserOptions != null) {
      TextFilter filter = parserOptions.getTextFilter();
      if (filter != null) {
        return filter.filterAttributeText(value, attribute, parent);
      }
    }
    return value;
  }
 
  private int getNextElementToParse()
    throws XMLStreamException{
      int token = parser.next();
      if (depthInSkipElement == 0 && token != XMLStreamConstants.START_ELEMENT){
        return token;        
      } else if (token == XMLStreamConstants.START_ELEMENT && isAcceptableToParse(parser.getName(), false) && depthInSkipElement == 0){
        return token;
      } else if (token == XMLStreamConstants.START_ELEMENT ){     
        depthInSkipElement++;
      } else if (token == XMLStreamConstants.END_ELEMENT ){ // otherwise skip like crazy     
        depthInSkipElement--;
      }  
      return getNextElementToParse();
  }
 
  /**
   * Method next.
   *
   * @return Returns int.
   * @throws OMException
   */
  public int next() throws OMException {
    try {
        if (done) {
            throw new OMException();
        }
        int token = getNextElementToParse();
        if (!cache) {
            return token;
        }
        switch (token) {
            case XMLStreamConstants.START_ELEMENT:
                lastNode = createOMElement();
                break;
            case XMLStreamConstants.START_DOCUMENT:
                document.setXMLVersion(
                  parser.getVersion() != null ?
                  parser.getVersion() : "1.0");
                document.setCharsetEncoding(
                  parser.getEncoding() != null ?
                  parser.getEncoding() : "utf-8");
                document.setStandalone(
                  parser.isStandalone() ? YES : NO);
                break;
            case XMLStreamConstants.CHARACTERS:
                lastNode = applyTextFilter(XMLStreamConstants.CHARACTERS);
                break;
            case XMLStreamConstants.CDATA:
                lastNode = applyTextFilter(XMLStreamConstants.CDATA);
                break;
            case XMLStreamConstants.END_ELEMENT:
                endElement();
                break;
            case XMLStreamConstants.END_DOCUMENT:
                done = true;
                ((OMContainerEx) this.document).setComplete(true);
                break;
            case XMLStreamConstants.SPACE:
                if (!parserOptions.getIgnoreWhitespace())
                  lastNode = createOMText(XMLStreamConstants.SPACE);
                break;
            case XMLStreamConstants.COMMENT:
                if (!parserOptions.getIgnoreComments())
                  createComment();
                break;
            case XMLStreamConstants.DTD:
                if (!parserOptions.getIgnoreDoctype())
                  createDTD();
                break;
            case XMLStreamConstants.PROCESSING_INSTRUCTION:
                if (!parserOptions.getIgnoreProcessingInstructions())
                  createPI();
                break;
            case XMLStreamConstants.ENTITY_REFERENCE:
                lastNode = createOMText(XMLStreamConstants.ENTITY_REFERENCE);
                break;
            default :
                throw new OMException();
        }
        return token;
    } catch (OMException e) {
        throw e;
    } catch (Exception e) {
        throw new OMException(e);
    }
  }
 
  private void initDocument(String name) {
    fomDocument = (Document) document;
    String enc = parser.getCharacterEncodingScheme();
    getDocument().setCharsetEncoding(enc != null ? enc : "utf-8");
    getDocument().setXMLVersion(
      parser.getVersion() != null ?
        parser.getVersion() : "1.0");
  }
 
  protected OMElement constructNode(OMContainer parent, String name) {
    OMElement element = null;
    if (fomDocument == null) {
      initDocument(name);
      parent = (OMContainer) fomDocument;
    }
    QName qname = parser.getName();
    element = fomfactory.createElement(qname, parent, this);
    if (element == null) {
      element = new FOMElement(qname, parent, fomfactory, this);
    }
    if (element != null) {
      this.processNamespaceData(element);
      processAttributes(element);
    }
    return element;
  }

  @Override
  protected void processAttributes(OMElement node) {
    int attribCount = parser.getAttributeCount();
    for (int i = 0; i < attribCount; i++) {
      QName attr = parser.getAttributeName(i);
      if (isAcceptableToParse(attr, true)) {
        String uri = parser.getAttributeNamespace(i);
        String prefix = parser.getAttributePrefix(i);
        OMNamespace namespace = null;
        if (uri != null && uri.length() > 0) {
            namespace = node.findNamespace(uri, prefix);
            if (namespace == null) {
                if (prefix == null || "".equals(prefix)) {
                    prefix = OMSerializerUtil.getNextNSPrefix();
                }
                namespace = node.declareNamespace(uri, prefix);
            }
        }
        String value = applyAttributeTextFilter(
          parser.getAttributeValue(i),
          attr, (Element)node);
        node.addAttribute(parser.getAttributeLocalName(i),
                value, namespace);
      }
    }
}
 
  @Override
  protected void endElement() {
    if (lastNode != null && lastNode.isComplete()) {
      OMElement parent = (OMElement) lastNode.getParent();
      ((OMNodeEx) parent).setComplete(true);
      lastNode = parent;
    } else {
        OMNode e = lastNode;
        if (e != null)
          ((OMNodeEx) e).setComplete(true);
    }
    depth--;
  }

  @SuppressWarnings("unchecked")
  public <T extends Element>Document<T> getFomDocument() {
    while ((fomDocument == null) && !done) {
      next();
    }
    return fomDocument;
  }
 
  public OMDocument getDocument() {
    return (OMDocument) getFomDocument();
  }
 
  public FOMFactory getFactory() {
    return fomfactory;
  }
 
  /**
   * Method createOMText.
   *
   * @return Returns OMNode.
   * @throws OMException
   */
  protected OMNode createOMText(String value, int textType) throws OMException {
      OMNode node = null;
      if (lastNode == null) {
          return null;
      } else if (!lastNode.isComplete()) {
          node = createOMText(value, (OMElement) lastNode, textType);
      } else {
          OMContainer parent = lastNode.getParent();
          if (!(parent instanceof OMDocument)) {
              node = createOMText(value, (OMElement) parent, textType);
          }
      }
      return node;
  }

  /**
   * This method will check whether the text can be optimizable using IS_BINARY flag.
   * If that is set then we try to get the data handler.
   *
   * @param omElement
   * @param textType
   * @return omNode
   */
  private OMNode createOMText(String value, OMElement omElement, int textType) {
      try {
          if (isDataHandlerAware && Boolean.TRUE == parser.getProperty(OMConstants.IS_BINARY)) {
              Object dataHandler = parser.getProperty(OMConstants.DATA_HANDLER);
              OMText text = omfactory.createOMText(dataHandler, true);
              omElement.addChild(text);
              return text;
          } else {
              return omfactory.createOMText(omElement, value, textType);
          }
      } catch (IllegalArgumentException e) {
          return omfactory.createOMText(omElement, value, textType);
      }
  }
}
TOP

Related Classes of org.apache.abdera.parser.stax.FOMBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.