You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2015/07/20 10:48:59 UTC
svn commit: r1691890 [4/14] - in /chemistry/portcmis: ./ PortCMIS/
PortCMIS/Properties/ PortCMIS/binding/ PortCMIS/binding/atompub/
PortCMIS/binding/browser/ PortCMIS/binding/browser/json/ PortCMIS/client/
PortCMIS/const/ PortCMIS/data/ PortCMIS/enum/ ...
Added: chemistry/portcmis/PortCMIS/binding/atompub/XmlUtils.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/atompub/XmlUtils.cs?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/PortCMIS/binding/atompub/XmlUtils.cs (added)
+++ chemistry/portcmis/PortCMIS/binding/atompub/XmlUtils.cs Mon Jul 20 08:48:57 2015
@@ -0,0 +1,281 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+using PortCMIS.Enums;
+using System.Globalization;
+using PortCMIS.Exceptions;
+
+namespace PortCMIS.Binding.AtomPub
+{
+ class XmlUtils
+ {
+
+ // --------------
+ // --- writer ---
+ // --------------
+
+ /**
+ * Creates a new XML writer.
+ */
+ public static XmlWriter createWriter(Stream stream)
+ {
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Encoding = Encoding.UTF8;
+ return XmlWriter.Create(stream, settings);
+ }
+
+ /**
+ * Starts a XML document.
+ */
+ public static void startXmlDocument(XmlWriter writer, string rootLocalName, string rootNamespace)
+ {
+ // writer.setPrefix(XmlConstants.PREFIX_ATOM, XmlConstants.NAMESPACE_ATOM);
+ // writer.setPrefix(XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS);
+ // writer.setPrefix(XmlConstants.PREFIX_RESTATOM, XmlConstants.NAMESPACE_RESTATOM);
+ // writer.setPrefix(XmlConstants.PREFIX_APACHE_CHEMISTY, XmlConstants.NAMESPACE_APACHE_CHEMISTRY);
+
+ writer.WriteStartDocument();
+ }
+
+ /**
+ * Ends a XML document.
+ */
+ public static void endXmlDocument(XmlWriter writer)
+ {
+ writer.WriteEndDocument();
+ writer.Dispose();
+ }
+
+ /**
+ * Writes a String tag.
+ */
+ public static void write(XmlWriter writer, string prefix, string ns, string tag, string value)
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ if (ns == null)
+ {
+ writer.WriteStartElement(tag);
+ }
+ else
+ {
+ writer.WriteStartElement(prefix, tag, ns);
+ }
+ writer.WriteString(value);
+ writer.WriteEndElement();
+ }
+
+ /**
+ * Writes an Integer tag.
+ */
+ public static void write(XmlWriter writer, string prefix, string ns, string tag, BigInteger? value)
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ write(writer, prefix, ns, tag, ((BigInteger)value).ToString("#", CultureInfo.InvariantCulture));
+ }
+
+ /**
+ * Writes a Decimal tag.
+ */
+ public static void write(XmlWriter writer, String prefix, String ns, String tag, decimal? value)
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ if (ns == null)
+ {
+ writer.WriteStartElement(tag);
+ }
+ else
+ {
+ writer.WriteStartElement(prefix, tag, ns);
+ }
+ writer.WriteValue(value);
+ writer.WriteEndElement();
+ }
+
+ /**
+ * Writes a DateTime tag.
+ */
+ public static void write(XmlWriter writer, String prefix, String ns, String tag, DateTime? value)
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ if (ns == null)
+ {
+ writer.WriteStartElement(tag);
+ }
+ else
+ {
+ writer.WriteStartElement(prefix, tag, ns);
+ }
+ writer.WriteValue(value);
+ writer.WriteEndElement();
+ }
+
+ /**
+ * Writes a Boolean tag.
+ */
+ public static void write(XmlWriter writer, string prefix, string ns, string tag, bool? value)
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ write(writer, prefix, ns, tag, (bool)value ? "true" : "false");
+ }
+
+ /**
+ * Writes an Enum tag.
+ */
+ public static void write(XmlWriter writer, String prefix, String ns, String tag, Enum value)
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ write(writer, prefix, ns, tag, value.GetCmisValue());
+ }
+
+
+ // ---------------
+ // ---- parser ---
+ // ---------------
+
+ /**
+ * Creates a new XML parser with OpenCMIS default settings.
+ */
+ public static XmlReader createParser(Stream stream)
+ {
+ XmlReaderSettings settings = new XmlReaderSettings();
+ settings.MaxCharactersInDocument = 0;
+ settings.CloseInput = true;
+ return XmlReader.Create(stream, settings);
+ }
+
+ /**
+ * Moves the parser to the next element.
+ */
+ public static bool next(XmlReader parser)
+ {
+ return parser.Read();
+ }
+
+ /**
+ * Skips a tag or subtree.
+ */
+ public static void skip(XmlReader parser)
+ {
+ parser.Skip();
+ }
+
+ /**
+ * Moves the parser to the next start element.
+ *
+ * @return <code>true</code> if another start element has been found,
+ * <code>false</code> otherwise
+ */
+ public static bool findNextStartElemenet(XmlReader parser)
+ {
+ while (true)
+ {
+ XmlNodeType nodeType = parser.NodeType;
+
+ if (nodeType == XmlNodeType.Element)
+ {
+ return true;
+ }
+
+ if (!parser.Read())
+ {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Parses a tag that contains text.
+ */
+ public static String readText(XmlReader parser, int maxLength)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ next(parser);
+
+ while (true)
+ {
+ XmlNodeType nodeType = parser.NodeType;
+ if (nodeType == XmlNodeType.EndElement)
+ {
+ break;
+ }
+ else if (nodeType == XmlNodeType.Text || nodeType == XmlNodeType.CDATA)
+ {
+ char[] buffer = new char[8 * 1024];
+
+ int len;
+ while ((len = parser.ReadValueChunk(buffer, 0, buffer.Length)) > 0)
+ {
+ if (sb.Length + len > maxLength)
+ {
+ throw new CmisInvalidArgumentException("String limit exceeded!");
+ }
+
+ sb.Append(buffer, 0, len);
+ }
+ }
+ else if (nodeType == XmlNodeType.Element)
+ {
+ throw new CmisInvalidArgumentException("Unexpected tag: " + parser.Name);
+ }
+
+ if (!next(parser))
+ {
+ break;
+ }
+ }
+
+ next(parser);
+
+ return sb.ToString();
+ }
+ }
+}
Added: chemistry/portcmis/PortCMIS/binding/atompub/XmlWalker.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/atompub/XmlWalker.cs?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/PortCMIS/binding/atompub/XmlWalker.cs (added)
+++ chemistry/portcmis/PortCMIS/binding/atompub/XmlWalker.cs Mon Jul 20 08:48:57 2015
@@ -0,0 +1,289 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. 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.
+*/
+
+using PortCMIS.Binding.AtomPub;
+using PortCMIS.Data.Extensions;
+using PortCMIS.Exceptions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+using PortCMIS.Enums;
+using System.Globalization;
+
+namespace PortCMIS.Binding.AtomPub
+{
+ internal abstract class XMLWalker<T>
+ {
+
+ public T walk(XmlReader parser)
+ {
+ T result = prepareTarget(parser, parser.LocalName, parser.NamespaceURI);
+
+ XmlUtils.next(parser);
+
+ // walk through all tags
+ while (true)
+ {
+ XmlNodeType nodeType = parser.NodeType;
+ if (nodeType == XmlNodeType.Element)
+ {
+ if (!read(parser, parser.LocalName, parser.NamespaceURI, result))
+ {
+ if (result is IExtensionsData)
+ {
+ handleExtension(parser, (IExtensionsData)result);
+ }
+ else
+ {
+ XmlUtils.skip(parser);
+ }
+ }
+ }
+ else if (nodeType == XmlNodeType.EndElement)
+ {
+ break;
+ }
+ else
+ {
+ if (!XmlUtils.next(parser))
+ {
+ break;
+ }
+ }
+ }
+
+ XmlUtils.next(parser);
+
+ return result;
+ }
+
+ protected bool isCmisNamespace(string ns)
+ {
+ return XmlConstants.NAMESPACE_CMIS == ns;
+ }
+
+ protected bool isAtomNamespace(string ns)
+ {
+ return XmlConstants.NAMESPACE_ATOM == ns;
+ }
+
+ protected bool isTag(string name, string tag)
+ {
+ return name == tag;
+ }
+
+ protected void handleExtension(XmlReader parser, IExtensionsData extData)
+ {
+ IList<ICmisExtensionElement> extensions = extData.Extensions;
+ if (extensions == null)
+ {
+ extensions = new List<ICmisExtensionElement>();
+ extData.Extensions = extensions;
+ }
+
+ if (extensions.Count + 1 > XMLConstraints.MAX_EXTENSIONS_WIDTH)
+ {
+ throw new CmisInvalidArgumentException("Too many extensions!");
+ }
+
+ extensions.Add(handleExtensionLevel(parser, 0));
+ }
+
+ private ICmisExtensionElement handleExtensionLevel(XmlReader parser, int level)
+ {
+ string localname = parser.Name;
+ string ns = parser.NamespaceURI;
+ IDictionary<string, string> attributes = null;
+ StringBuilder sb = new StringBuilder();
+ IList<ICmisExtensionElement> children = null;
+
+ if (parser.HasAttributes)
+ {
+ attributes = new Dictionary<string, string>();
+
+ while (parser.MoveToNextAttribute())
+ {
+ attributes.Add(parser.Name, parser.Value);
+ }
+ }
+
+ XmlUtils.next(parser);
+
+ while (true)
+ {
+ XmlNodeType nodeType = parser.NodeType;
+ if (nodeType == XmlNodeType.EndElement)
+ {
+ break;
+ }
+ else if (nodeType == XmlNodeType.Text)
+ {
+ string s = parser.Value;
+ if (s != null)
+ {
+ if (sb.Length + s.Length > XMLConstraints.MAX_STRING_LENGTH)
+ {
+ throw new CmisInvalidArgumentException("String limit exceeded!");
+ }
+ sb.Append(s);
+ }
+ }
+ else if (nodeType == XmlNodeType.Element)
+ {
+ if (level + 1 > XMLConstraints.MAX_EXTENSIONS_DEPTH)
+ {
+ throw new CmisInvalidArgumentException("Extensions tree too deep!");
+ }
+
+ if (children == null)
+ {
+ children = new List<ICmisExtensionElement>();
+ }
+
+ if (children.Count + 1 > XMLConstraints.MAX_EXTENSIONS_WIDTH)
+ {
+ throw new CmisInvalidArgumentException("Extensions tree too wide!");
+ }
+
+ children.Add(handleExtensionLevel(parser, level + 1));
+
+ continue;
+ }
+
+ if (!XmlUtils.next(parser))
+ {
+ break;
+ }
+ }
+
+ XmlUtils.next(parser);
+
+ CmisExtensionElement element = new CmisExtensionElement()
+ {
+ Name = localname,
+ Namespace = ns,
+ Attributes = attributes
+ };
+
+ if (children != null)
+ {
+ element.Children = children;
+ }
+ else
+ {
+ element.Value = sb.ToString();
+ }
+
+ return element;
+ }
+
+ protected IList<S> addToList<S>(IList<S> list, S value)
+ {
+ if (list == null)
+ {
+ list = new List<S>();
+ }
+ list.Add(value);
+
+ return list;
+ }
+
+ protected string readText(XmlReader parser)
+ {
+ return XmlUtils.readText(parser, XMLConstraints.MAX_STRING_LENGTH);
+ }
+
+ protected bool? readBoolean(XmlReader parser)
+ {
+ parser.MoveToContent();
+
+ try
+ {
+ return parser.ReadContentAsBoolean();
+ }
+ catch (Exception e)
+ {
+ throw new CmisInvalidArgumentException("Invalid boolean value!", e);
+ }
+ }
+
+ protected BigInteger readInteger(XmlReader parser)
+ {
+ string value = readText(parser);
+
+ try
+ {
+ return BigInteger.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
+ }
+ catch (Exception e)
+ {
+ throw new CmisInvalidArgumentException("Invalid integer value!", e);
+ }
+ }
+
+ protected decimal readDecimal(XmlReader parser)
+ {
+ parser.MoveToContent();
+
+ try
+ {
+ return parser.ReadContentAsDecimal();
+ }
+ catch (Exception e)
+ {
+ throw new CmisInvalidArgumentException("Invalid decimal value!", e);
+ }
+ }
+
+ protected DateTime readDateTime(XmlReader parser)
+ {
+ string value = readText(parser);
+
+ DateTime result = DateTimeHelper.ParseISO8601(value);
+ if (result == null)
+ {
+ throw new CmisInvalidArgumentException("Invalid datetime value!");
+ }
+
+ return result;
+ }
+
+ protected E readEnum<E>(XmlReader parser)
+ {
+ return readText(parser).GetCmisEnum<E>();
+ }
+
+ protected abstract T prepareTarget(XmlReader parser, string localname, string ns);
+
+ protected abstract bool read(XmlReader parser, string localname, string ns, T target);
+
+ }
+
+ internal class XMLConstraints
+ {
+ public const int MAX_STRING_LENGTH = 100 * 1024;
+
+ public const int MAX_EXTENSIONS_WIDTH = 500;
+ public const int MAX_EXTENSIONS_DEPTH = 20;
+ }
+}
\ No newline at end of file