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