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 + -
显示快捷键?