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 2013/02/13 15:37:28 UTC

svn commit: r1445627 [2/2] - in /chemistry/opencmis/trunk: chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/ chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/ap...

Added: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/XMLWalker.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/XMLWalker.java?rev=1445627&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/XMLWalker.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/XMLWalker.java Wed Feb 13 14:37:28 2013
@@ -0,0 +1,249 @@
+/*
+ * 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.
+ */
+package org.apache.chemistry.opencmis.commons.impl;
+
+import static org.apache.chemistry.opencmis.commons.impl.XMLUtils.next;
+
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
+import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.CmisExtensionElementImpl;
+
+public abstract class XMLWalker<T> {
+
+    public T walk(XMLStreamReader parser) throws XMLStreamException {
+        final T result = prepareTarget(parser, parser.getName());
+
+        next(parser);
+
+        // walk through all tags
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XMLStreamReader.START_ELEMENT) {
+                QName name = parser.getName();
+                if (!read(parser, name, result) && (result instanceof ExtensionsData)) {
+                    handleExtension(parser, (ExtensionsData) result);
+                }
+            } else if (event == XMLStreamReader.END_ELEMENT) {
+                break;
+            } else {
+                if (!next(parser)) {
+                    break;
+                }
+            }
+        }
+
+        next(parser);
+
+        return result;
+    }
+
+    protected boolean isCmisNamespace(QName name) {
+        return Constants.NAMESPACE_CMIS.hashCode() == name.getNamespaceURI().hashCode()
+                && Constants.NAMESPACE_CMIS.equals(name.getNamespaceURI());
+    }
+
+    protected boolean isAtomNamespace(QName name) {
+        return Constants.NAMESPACE_ATOM.hashCode() == name.getNamespaceURI().hashCode()
+                && Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI());
+    }
+
+    protected boolean isTag(QName name, String tag) {
+        return tag.hashCode() == name.getLocalPart().hashCode() && tag.equals(name.getLocalPart());
+    }
+
+    private void handleExtension(XMLStreamReader parser, ExtensionsData extData) throws XMLStreamException {
+        List<CmisExtensionElement> extensions = extData.getExtensions();
+        if (extensions == null) {
+            extensions = new ArrayList<CmisExtensionElement>();
+            extData.setExtensions(extensions);
+        }
+
+        if (extensions.size() + 1 > XMLConstraints.MAX_EXTENSIONS_WIDTH) {
+            throw new CmisInvalidArgumentException("Too many extensions!");
+        }
+
+        extensions.add(handleExtensionLevel(parser, 0));
+    }
+
+    private CmisExtensionElement handleExtensionLevel(final XMLStreamReader parser, final int level)
+            throws XMLStreamException {
+        final QName name = parser.getName();
+        Map<String, String> attributes = null;
+        StringBuilder sb = new StringBuilder();
+        List<CmisExtensionElement> children = null;
+
+        if (parser.getAttributeCount() > 0) {
+            attributes = new HashMap<String, String>();
+
+            for (int i = 0; i < parser.getAttributeCount(); i++) {
+                attributes.put(parser.getAttributeLocalName(i), parser.getAttributeValue(i));
+            }
+        }
+
+        next(parser);
+
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XMLStreamReader.END_ELEMENT) {
+                break;
+            } else if (event == XMLStreamReader.CHARACTERS) {
+                String s = parser.getText();
+                if (s != null) {
+                    if (sb.length() + s.length() > XMLConstraints.MAX_STRING_LENGTH) {
+                        throw new CmisInvalidArgumentException("String limit exceeded!");
+                    }
+                    sb.append(s);
+                }
+            } else if (event == XMLStreamReader.START_ELEMENT) {
+                if (level + 1 > XMLConstraints.MAX_EXTENSIONS_DEPTH) {
+                    throw new CmisInvalidArgumentException("Extensions tree too deep!");
+                }
+
+                if (children == null) {
+                    children = new ArrayList<CmisExtensionElement>();
+                }
+
+                if (children.size() + 1 > XMLConstraints.MAX_EXTENSIONS_WIDTH) {
+                    throw new CmisInvalidArgumentException("Extensions tree too wide!");
+                }
+
+                children.add(handleExtensionLevel(parser, level + 1));
+            }
+
+            if (!next(parser)) {
+                break;
+            }
+        }
+
+        next(parser);
+
+        if (children != null) {
+            return new CmisExtensionElementImpl(name.getNamespaceURI(), name.getLocalPart(), attributes, children);
+        } else {
+            return new CmisExtensionElementImpl(name.getNamespaceURI(), name.getLocalPart(), attributes, sb.toString());
+        }
+    }
+
+    protected <S> List<S> addToList(List<S> list, S value) {
+        if (list == null) {
+            list = new ArrayList<S>();
+        }
+        list.add(value);
+
+        return list;
+    }
+
+    protected String readText(final XMLStreamReader parser) throws XMLStreamException {
+        return XMLUtils.readText(parser, XMLConstraints.MAX_STRING_LENGTH);
+    }
+
+    protected Boolean readBoolean(final XMLStreamReader parser) throws XMLStreamException {
+        String value = readText(parser);
+        if (value == null) {
+            return null;
+        }
+
+        if ("true".equals(value) || "1".equals(value)) {
+            return Boolean.TRUE;
+        }
+
+        if ("false".equals(value) || "0".equals(value)) {
+            return Boolean.FALSE;
+        }
+
+        throw new CmisInvalidArgumentException("Invalid boolean value!");
+    }
+
+    protected BigInteger readInteger(final XMLStreamReader parser) throws XMLStreamException {
+        String value = readText(parser);
+        if (value == null) {
+            return null;
+        }
+
+        try {
+            return new BigInteger(value);
+        } catch (NumberFormatException e) {
+            throw new CmisInvalidArgumentException("Invalid integer value!", e);
+        }
+    }
+
+    protected BigDecimal readDecimal(final XMLStreamReader parser) throws XMLStreamException {
+        String value = readText(parser);
+        if (value == null) {
+            return null;
+        }
+
+        try {
+            return new BigDecimal(value);
+        } catch (NumberFormatException e) {
+            throw new CmisInvalidArgumentException("Invalid decimal value!", e);
+        }
+    }
+
+    protected GregorianCalendar readDateTime(final XMLStreamReader parser) throws XMLStreamException {
+        String value = readText(parser);
+        if (value == null) {
+            return null;
+        }
+
+        GregorianCalendar result = DateTimeHelper.parseXmlDateTime(value);
+        if (result == null) {
+            throw new CmisInvalidArgumentException("Invalid datetime value!");
+        }
+
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <E extends Enum<E>> E readEnum(final XMLStreamReader parser, final Class<E> clazz) throws XMLStreamException {
+        String value = readText(parser);
+        if (value == null) {
+            return null;
+        }
+
+        try {
+            Method m = clazz.getMethod("fromValue", String.class);
+            return (E) m.invoke(null, value);
+        } catch (Exception e) {
+            if (e instanceof IllegalArgumentException) {
+                return null;
+            } else {
+                throw new CmisInvalidArgumentException("Invalid enum value!", e);
+            }
+        }
+    }
+
+    protected abstract T prepareTarget(XMLStreamReader parser, QName name) throws XMLStreamException;
+
+    protected abstract boolean read(XMLStreamReader parser, QName name, T target) throws XMLStreamException;
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/XMLWalker.java
------------------------------------------------------------------------------
    svn:eol-style = native