xml.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,012 行 · 第 1/2 页

JAVA
1,012
字号
/* * Copyright (c) 1998-2005 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Charles Reich */package com.caucho.quercus.lib.xml;import com.caucho.quercus.QuercusException;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.Reference;import com.caucho.quercus.env.*;import com.caucho.util.L10N;import org.xml.sax.*;import org.xml.sax.helpers.DefaultHandler;import javax.xml.parsers.ParserConfigurationException;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import java.io.IOException;import java.io.StringReader;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.HashMap;import java.util.logging.Level;import java.util.logging.Logger;/** * XML object oriented API facade */public class Xml {  private static final Logger log = Logger.getLogger(Xml.class.getName());  private static final L10N L = new L10N(Xml.class);  /**   * XML_OPTION_CASE_FOLDING is enabled by default   *   * only affects startElement (including attribute   * names) and endElement handlers.   */  private boolean _xmlOptionCaseFolding = true;  private String _xmlOptionTargetEncoding;  /**   *  XML_OPTION_SKIP_TAGSTART specifies how many chars   *  should be skipped in the beginning of a tag name (default = 0)   *   *  XXX: Not yet implemented   */  private long _xmlOptionSkipTagstart = 0;  /**   *  XXX: _xmlOptionSkipWhite not yet implemented   */  private boolean _xmlOptionSkipWhite = false;  private Env _env;  /** XXX: _separator is set by xml_parse_create_ns but   *  not yet used.  Default value is ":"   *  Possibly should report error if user wants to use   *  anything other than ":"   */  private String _separator;  private int _errorCode = XmlModule.XML_ERROR_NONE;  private String _errorString;  private Callback _startElementHandler;  private Callback _endElementHandler;  private Callback _characterDataHandler;  private Callback _processingInstructionHandler;  private Callback _defaultHandler;  private Callback _startNamespaceDeclHandler;  private Callback _endNamespaceDeclHandler;  private Callback _notationDeclHandler;  private Callback _unparsedEntityDeclHandler;  private Value _parser;  private Value _obj;  SAXParserFactory _factory = SAXParserFactory.newInstance();  private StringValue _xmlString;  private XmlHandler _xmlHandler;  public Xml(Env env,             String outputEncoding,             String separator)  {    _env = env;    _xmlOptionTargetEncoding = outputEncoding;    _parser = _env.wrapJava(this);    _separator = separator;  }  public int getLine()  {    if (_xmlHandler != null)      return _xmlHandler.getLine();    else      return 0;  }  public int getColumn()  {    if (_xmlHandler != null)      return _xmlHandler.getColumn();    else      return 0;  }  public int getByteIndex()  {    return 0;  }  public int getErrorCode()  {    return _errorCode;  }  public String getErrorString()  {    return _errorString;  }  /**   * Sets the element handler functions for the XML parser.   *   * @param startElementHandler must exist when xml_parse is called   * @param endElementHandler must exist when xml_parse is called   * @return true always even if handlers are disabled   */  public boolean xml_set_element_handler(Value startElementHandler,                                         Value endElementHandler)  {    if (_obj == null) {      _startElementHandler = _env.createCallback(startElementHandler);      _endElementHandler = _env.createCallback(endElementHandler);    } else {      if (! startElementHandler.isEmpty()) {        Value value = new ArrayValueImpl();        value.put(_obj);        value.put(startElementHandler);        _startElementHandler = _env.createCallback(value);      }      if (! endElementHandler.isEmpty()) {        Value value = new ArrayValueImpl();        value.put(_obj);        value.put(endElementHandler);        _endElementHandler = _env.createCallback(value);      }    }    return true;  }  /**   * Sets the character data handler function.   *   * @param handler can be empty string or FALSE   * @return true always even if handler is disabled   */  public boolean xml_set_character_data_handler(Value handler)  {    if (_obj == null) {      _characterDataHandler = _env.createCallback(handler);    } else {      Value value = new ArrayValueImpl();      value.put(_obj);      value.put(handler);      _characterDataHandler = _env.createCallback(value);    }    return true;  }  /**   * The php documentation is very vague as to the purpose   * of the default handler.   *   * We are interpreting it as an alternative to the character   * data handler.   *   * If character handler is defined, then use that.  Otherwise,   * use default handler, if it is defined.   *   * XXX: Need to confirm that this is appropriate   *   * @param handler   * @return true always even if handler is disabled   */  public boolean xml_set_default_handler(Value handler)  {    if (_obj == null) {      _defaultHandler = _env.createCallback(handler);    } else {      Value value = new ArrayValueImpl();      value.put(_obj);      value.put(handler);      _defaultHandler = _env.createCallback(value);    }    return true;  }  /**   * Sets the processing instruction handler function   *   * @param processingInstructionHandler   * @return true always even if handler is disabled   */  public boolean xml_set_processing_instruction_handler(Value processingInstructionHandler)  {    if (_obj == null) {      _processingInstructionHandler = _env.createCallback(processingInstructionHandler);    } else {      Value value = new ArrayValueImpl();      value.put(_obj);      value.put(processingInstructionHandler);      _processingInstructionHandler = _env.createCallback(value);    }    return true;  }  /**   * Sets the startPrefixMapping handler   *   * @param startNamespaceDeclHandler   * @return true always even if handler is disabled   */  public boolean xml_set_start_namespace_decl_handler(Value startNamespaceDeclHandler)  {    if (_obj == null) {      _startNamespaceDeclHandler = _env.createCallback(startNamespaceDeclHandler);    } else {      Value value = new ArrayValueImpl();      value.put(_obj);      value.put(startNamespaceDeclHandler);      _startNamespaceDeclHandler = _env.createCallback(value);    }    return true;  }  /**   * Sets the unparsedEntityDecl handler   *   * @param handler   * @return true always even if handler is disabled   */  public boolean xml_set_unparsed_entity_decl_handler(Value handler)  {    if (_obj == null) {      _unparsedEntityDeclHandler = _env.createCallback(handler);    } else {      Value value = new ArrayValueImpl();      value.put(_obj);      value.put(handler);      _unparsedEntityDeclHandler = _env.createCallback(value);    }    return true;  }  /**   * Sets the endPrefixMapping handler   *   * @param endNamespaceDeclHandler   * @return true always even if handler is disabled   */  public boolean xml_set_end_namespace_decl_handler(Value endNamespaceDeclHandler)  {    if (_obj == null) {      _endNamespaceDeclHandler = _env.createCallback(endNamespaceDeclHandler);    } else {      Value value = new ArrayValueImpl();      value.put(_obj);      value.put(endNamespaceDeclHandler);      _endNamespaceDeclHandler = _env.createCallback(value);    }    return true;  }  /**   * Sets the notationDecl handler   *   * @param handler   * @return true always even if handler is disabled   */  public boolean xml_set_notation_decl_handler(Value handler)  {    if (_obj == null) {      _notationDeclHandler = _env.createCallback(handler);    } else {      Value value = new ArrayValueImpl();      value.put(_obj);      value.put(handler);      _notationDeclHandler = _env.createCallback(value);    }    return true;  }  /**   * sets the object which houses all the callback functions   *   * @param obj   * @return returns true unless obj == null   */  public boolean xml_set_object(Value obj)  {    if (obj == null)      return false;    _obj = obj;    return true;  }  /**   * xml_parse will keep accumulating "data" until   * either is_final is true or omitted   *   * @param data   * @param isFinal   * @return   * @throws IOException   * @throws SAXException   * @throws ParserConfigurationException   */  public int xml_parse(Env env,                       StringValue data,                       @Optional("true") boolean isFinal)    throws Exception  {    if (_xmlString == null)      _xmlString = data.createStringBuilder();        _xmlString.append(data);    if (isFinal) {      InputSource is;            if (_xmlString.isUnicode())        is = new InputSource(_xmlString.toReader("utf-8"));      else if (_xmlOptionTargetEncoding != null)        is = new InputSource(_xmlString.toReader(_xmlOptionTargetEncoding));      else        is = new InputSource(_xmlString.toInputStream());            if (_xmlOptionTargetEncoding == null)        _xmlOptionTargetEncoding = is.getEncoding();            try {        _errorCode = XmlModule.XML_ERROR_NONE;        _errorString = null;        _xmlHandler = new XmlHandler();	        SAXParser saxParser = _factory.newSAXParser();        saxParser.parse(is, _xmlHandler);      } catch (SAXException e) {        _errorCode = XmlModule.XML_ERROR_SYNTAX;        _errorString = e.toString();        log.log(Level.FINE, e.getMessage(), e);        return 0;      } catch (IOException e) {        _errorCode = XmlModule.XML_ERROR_SYNTAX;        _errorString = e.toString();        log.log(Level.FINE, e.getMessage(), e);        return 0;      } catch (Exception e) {        _errorCode = XmlModule.XML_ERROR_SYNTAX;        _errorString = e.toString();                log.log(Level.FINE, e.toString(), e);        return 0;      }           }    return 1;  }  /**   * Parses data into 2 parallel array structures.   *   * @param data   * @param valsV   * @param indexV   * @return 0 for failure, 1 for success   */  public int xml_parse_into_struct(Env env,                                   StringValue data,                                   @Reference Value valsV,                                   @Optional @Reference Value indexV)    throws Exception  {    ArrayValueImpl valueArray = new ArrayValueImpl();    ArrayValueImpl indexArray = new ArrayValueImpl();        valsV.set(valueArray);    indexV.set(indexArray);        if (data == null || data.length() == 0)      return 0;    if (_xmlString == null)      _xmlString = data.toStringBuilder();    InputSource is;        if (_xmlString.isUnicode())      is = new InputSource(_xmlString.toReader("utf-8"));    else      is = new InputSource(_xmlString.toInputStream());    try {      SAXParser saxParser = _factory.newSAXParser();      saxParser.parse(is, new StructHandler(valueArray, indexArray));    } catch (SAXException e) {      _errorCode = XmlModule.XML_ERROR_SYNTAX;      _errorString = e.toString();            log.log(Level.FINE, e.toString(), e);            return 0;    } catch (IOException e) {      _errorCode = XmlModule.XML_ERROR_SYNTAX;      _errorString = e.toString();            log.log(Level.FINE, e.toString(), e);            return 0;    } catch (Exception e) {      _errorCode = XmlModule.XML_ERROR_SYNTAX;      _errorString = e.toString();            log.log(Level.FINE, e.toString(), e);            return 0;    }    return 1;  }  /**   *  sets one of the following:   *  _xmlOptionCaseFolding (ENABLED / DISABLED)   *  _xmlOptionTargetEncoding (String)   *  _xmlOptionSkipTagstart (int)   *  _xmlOptionSkipWhite (ENABLED / DISABLED)   *   * XXX: currently only _xmlOptionCaseFolding actually does something   *   * @param option   * @param value   * @return true unless value could not be set   */  public boolean xml_parser_set_option(int option,                                       Value value)  {    switch(option) {      case XmlModule.XML_OPTION_CASE_FOLDING:        _xmlOptionCaseFolding = value.toBoolean();        return true;      case XmlModule.XML_OPTION_SKIP_TAGSTART:        _xmlOptionSkipTagstart = value.toLong();        return true;      case XmlModule.XML_OPTION_SKIP_WHITE:        _xmlOptionSkipWhite = value.toBoolean();        return true;      case XmlModule.XML_OPTION_TARGET_ENCODING:        _xmlOptionTargetEncoding = value.toString();        return true;      default:        return false;    }  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?