simplexmlelement.java

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

JAVA
1,198
字号
/* * Copyright (c) 1998-2008 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.simplexml;import com.caucho.quercus.annotation.Name;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.ReturnNullAsFalse;import com.caucho.quercus.annotation.EntrySet;import com.caucho.quercus.env.*;import com.caucho.quercus.program.JavaClassDef;import com.caucho.util.L10N;import com.caucho.vfs.Path;import com.caucho.vfs.ReadStream;import com.caucho.vfs.WriteStream;import org.w3c.dom.Attr;import org.w3c.dom.Document;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import javax.xml.xpath.XPath;import javax.xml.xpath.XPathConstants;import javax.xml.xpath.XPathExpressionException;import javax.xml.xpath.XPathFactory;import java.io.IOException;import java.io.InputStream;import java.io.StringReader;import java.util.*;import java.util.logging.*;/** * SimpleXMLElement object oriented API facade. * Also acts as the DOM document. */public class SimpleXMLElement implements Map.Entry<String,Object>{  private static final Logger log    = Logger.getLogger(SimpleXMLElement.class.getName());  private static final L10N L = new L10N(SimpleXMLElement.class);    SimpleXMLElement _parent;    protected String _name;    // mixed content is all combined  protected StringValue _text;    protected ArrayList<SimpleXMLElement> _children;  protected ArrayList<SimpleXMLElement> _attributes;    String _namespace;  String _prefix;    LinkedHashMap<String, String> _namespaceMap;    protected Env _env;  protected QuercusClass _cls;    protected SimpleXMLElement(Env env,                             QuercusClass cls)  {    _env = env;    _cls = cls;  }  protected SimpleXMLElement(Env env, QuercusClass cls,                             SimpleXMLElement parent, String name)  {    _env = env;    _cls = cls;    _parent = parent;    _name = name;  }  protected SimpleXMLElement(Env env,                             QuercusClass cls,                             SimpleXMLElement parent,                             String name,                             String namespace)  {    _env = env;    _cls = cls;    _parent = parent;    int p = name.indexOf(':');    if (p > 0) {      _name = name.substring(p + 1);      _prefix = name.substring(0, p);    }    else      _name = name;    if ("".equals(_name))      throw new IllegalArgumentException(L.l("name can't be empty"));    _namespace = namespace;    if (namespace != null) {      if (_prefix == null)        _prefix = "";      if (! hasNamespace(_prefix, namespace)) {        String ns;        if ("".equals(_prefix))          ns = "xmlns";        else          ns = "xmlns:" + _prefix;        addNamespaceAttribute(env, ns, namespace);      }    }  }    protected static Value create(Env env,                                QuercusClass cls,                                Value data,                                int options,                                boolean dataIsUrl,                                Value namespaceV,                                boolean isPrefix)  {    if (data.length() == 0) {      env.warning(L.l("xml data must have length greater than 0"));      return BooleanValue.FALSE;    }        try {      String namespace = null;      if (! namespaceV.isNull())        namespace = namespaceV.toString();            Node node = parse(env, data, options, dataIsUrl, namespace, isPrefix);            if (node == null) {        return BooleanValue.FALSE;      }      SimpleXMLElement elt        = buildNode(env, cls, null, node, namespace, isPrefix);            return wrapJava(env, cls, elt);          } catch (IOException e) {      env.warning(e);            return BooleanValue.FALSE;    }    catch (ParserConfigurationException e) {      env.warning(e);            return BooleanValue.FALSE;    }    catch (SAXException e) {      env.warning(e);            return BooleanValue.FALSE;    }  }    protected static Value wrapJava(Env env,                                  QuercusClass cls,                                  SimpleXMLElement element)  {    if (! "SimpleXMLElement".equals(cls.getName()))      return new ObjectExtJavaValue(cls, element, cls.getJavaClassDef());    else      return new JavaValue(env, element, cls.getJavaClassDef());  }    protected QuercusClass getQuercusClass()  {    return _cls;  }    protected void setQuercusClass(QuercusClass cls)  {    _cls = cls;  }  protected void addNamespace(String prefix, String namespace)  {    if (prefix == null)      prefix = "";        if (hasNamespace(prefix, namespace))      return;    if (_namespaceMap == null)      _namespaceMap = new LinkedHashMap<String,String>();          _namespaceMap.put(prefix, namespace);  }  protected boolean hasNamespace(String prefix, String namespace)  {    String uri = getNamespace(prefix);    return uri != null && uri.equals(namespace);  }  protected String getNamespace(String prefix)  {    if (prefix == null)      prefix = "";    if (_namespaceMap != null) {      String uri = _namespaceMap.get(prefix);      if (uri != null)        return uri;    }    if (_parent != null)      return _parent.getNamespace(prefix);    else      return null;  }    /**   * Returns a new instance based on the xml from 'data'.   *    * @param env   * @param data xml data   * @param options   * @param dataIsUrl   * @param namespaceV   * @param isPrefix   */  public static Value __construct(Env env,                                  Value data,                                  @Optional int options,                                  @Optional boolean dataIsUrl,                                  @Optional Value namespaceV,                                  @Optional boolean isPrefix)  {     QuercusClass cls = env.getCallingClass();        if (cls == null)      cls = env.getClass("SimpleXMLElement");        return create(env, cls,                  data, options, dataIsUrl, namespaceV, isPrefix);  }  protected String getName()  {    return _name;  }  protected String getNamespace()  {    return _namespace != null ? _namespace : "";  }  protected SimpleXMLElement getOwner()  {    return this;  }  protected boolean isElement()  {    return true;  }  protected void setText(StringValue text)  {    _text = text.createStringBuilder().append(text);  }  protected void addText(StringValue text)  {    if (_text == null)      _text = text.createStringBuilder();        _text = _text.append(text);  }    protected boolean isSameNamespace(String namespace)  {    if (namespace == null || namespace.length() == 0)      return true;    else      return namespace.equals(_namespace);  }    protected boolean isSamePrefix(String prefix)  {    if (prefix == null || prefix.length() == 0)      return true;    return prefix.equals(_prefix);  }  protected SimpleXMLElement getAttribute(String name)  {    if (_attributes == null)      return null;    int size = _attributes.size();    for (int i = 0; i < size; i++) {      SimpleXMLElement attr = _attributes.get(i);      if (attr.getName().equals(name))	return attr;    }    return null;  }  private SimpleXMLElement getElement(String name)  {    if (_children == null)      return null;    int size = _children.size();    for (int i = 0; i < size; i++) {      SimpleXMLElement elt = _children.get(i);      if (elt.getName().equals(name))        return elt;    }        return null;  }  //  // Map.Entry api for iterator  //  public String getKey()  {    return _name;  }  public Object getValue()  {    return wrapJava(_env, _cls, this);  }  public Object setValue(Object value)  {    return wrapJava(_env, _cls, this);  }  /**   * Adds an attribute to this node.   */  public void addAttribute(Env env,                           String name,                           StringValue value,                           @Optional String namespace)  {    if (namespace != null && namespace.length() > 0) {      int colonIndex = name.indexOf(":");            // php/1x42      if (colonIndex <= 0 || colonIndex >= name.length()) {        env.warning(L.l("Adding attributes with namespaces requires attribute name with a prefix"));        return;      }    }        if (_attributes == null)      _attributes = new ArrayList<SimpleXMLElement>();    SimpleXMLAttribute attr      = new SimpleXMLAttribute(env, _cls, this, name, namespace, value);        _attributes.add(attr);  }  /**   * Adds a namespace attribute to this node.   */  protected void addNamespaceAttribute(Env env, String name,                                       String namespace)  {    if (namespace == null || "".equals(namespace))      return;        if (_attributes == null)      _attributes = new ArrayList<SimpleXMLElement>();    SimpleXMLAttribute attr      = new SimpleXMLAttribute(env, _cls,                               this, name, "",                               env.createString(namespace));    int p = name.indexOf(':');    if (p > 0) {      String prefix = name.substring(p + 1);      addNamespace(prefix, namespace);    }    else {      if (_namespace == null)        _namespace = namespace;            addNamespace("", namespace);    }    for (int i = _attributes.size() - 1; i >= 0; i--) {      SimpleXMLElement oldAttr = _attributes.get(i);      if (oldAttr.getName().equals(name)	  && oldAttr.getNamespace().equals(namespace)) {	_attributes.set(i, attr);	return;      }    }        _attributes.add(attr);  }  /**   * Adds an attribute to this node.   */  public void addAttribute(SimpleXMLElement attr)  {    if (_attributes == null)      _attributes = new ArrayList<SimpleXMLElement>();        _attributes.add(attr);  }  /**   * Adds a child to this node.   *    * @param env   * @param name of the child node   * @param value of the text node of the child   * @param namespace   * @return   */  public Value addChild(Env env,                        String name,                        String value,                        @Optional Value namespaceV)  {    String namespace;    if (! namespaceV.isNull())      namespace = namespaceV.toString();    else      namespace = _namespace;        SimpleXMLElement child      = new SimpleXMLElement(env, _cls, this, name, namespace);        child.setText(env.createString(value));    addChild(child);    return wrapJava(env, _cls, child);  }  private void addChild(SimpleXMLElement child)  {    if (_children == null)      _children = new ArrayList<SimpleXMLElement>();    _children.add(child);  }    /**   * Returns the attributes of this node.   *    * @param env   * @param namespaceV   * @param isPrefix   */  public Value attributes(Env env,                          @Optional Value namespaceV,                          @Optional boolean isPrefix)  {    String namespace = null;    if (! namespaceV.isNull())      namespace = namespaceV.toString();    SimpleXMLElement attrList      = new SimpleXMLAttribute(env, _cls, this, _name, namespace, null);    if (_attributes != null) {      for (SimpleXMLElement attr : _attributes) {	if (attrList.isSameNamespace(attr.getNamespace()))	  attrList.addAttribute(attr);      }    }    return wrapJava(env, _cls, attrList);  }    /**   * Returns all the children of this node, including the attributes of   * this node.   *    * @param env   * @param namespaceV   * @param isPrefix   */  public Value children(Env env,                        @Optional Value namespaceV,                        @Optional boolean isPrefix)  {    String namespace = null;    if (! namespaceV.isNull())      namespace = namespaceV.toString();        SimpleXMLElement result      = new SimpleXMLChildren(env, _cls, this, getName());    if (_attributes != null) {      for (SimpleXMLElement attr : _attributes) {        if (attr.isSameNamespace(namespace))          result.addAttribute(attr);      }    }    if (_children != null) {      for (SimpleXMLElement child : _children) {        if (isPrefix) {          if (child.isSamePrefix(namespace)) {          }        }        else {          if (child.isSameNamespace(namespace)) {            result.addChild(child);          }        }      }    }    return wrapJava(env, _cls, result);  }  //  // XML parsing and generation  //    private static Node parse(Env env,                            Value data,                            int options,                            boolean dataIsUrl,                            String namespace,                            boolean isPrefix)    throws IOException,           ParserConfigurationException,           SAXException  {    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    DocumentBuilder builder = factory.newDocumentBuilder();    Document document = null;    if (dataIsUrl) {      Path path = env.lookup(data.toString());      // PHP throws an Exception instead      if (path == null) {        log.log(Level.FINE, L.l("Cannot read file/URL '{0}'", data));        env.warning(L.l("Cannot read file/URL '{0}'", data));        return null;

⌨️ 快捷键说明

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