You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by af...@apache.org on 2014/06/03 08:57:15 UTC
svn commit: r1599430 [4/5] - in /openoffice/trunk/main/ooxml: ./ source/
source/framework/ source/framework/JavaOOXMLParser/
source/framework/JavaOOXMLParser/.settings/
source/framework/JavaOOXMLParser/src/
source/framework/JavaOOXMLParser/src/org/ sou...
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/RequestVisitor.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/RequestVisitor.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/RequestVisitor.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/RequestVisitor.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,119 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.optimize;
+
+import org.apache.openoffice.ooxml.schema.model.base.INode;
+import org.apache.openoffice.ooxml.schema.model.base.NodeVisitorAdapter;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+import org.apache.openoffice.ooxml.schema.model.complex.ComplexType;
+import org.apache.openoffice.ooxml.schema.model.complex.Element;
+import org.apache.openoffice.ooxml.schema.model.complex.ElementReference;
+import org.apache.openoffice.ooxml.schema.model.complex.Extension;
+import org.apache.openoffice.ooxml.schema.model.complex.GroupReference;
+import org.apache.openoffice.ooxml.schema.model.schema.Schema;
+import org.apache.openoffice.ooxml.schema.model.simple.List;
+import org.apache.openoffice.ooxml.schema.model.simple.SimpleTypeReference;
+import org.apache.openoffice.ooxml.schema.model.simple.Union;
+
+/** A visitor that is called for all nodes of a complex or simple type to mark
+ * the referenced types as being used.
+ */
+public class RequestVisitor
+ extends NodeVisitorAdapter
+{
+ RequestVisitor (
+ final Schema aSourceSchema,
+ final SchemaOptimizer aOptimizer)
+ {
+ maSourceSchema = aSourceSchema;
+ maSchemaOptimizer = aOptimizer;
+ }
+
+
+ @Override public void Visit (final ComplexType aComplexType)
+ {
+ for (final INode aAttribute : aComplexType.GetAttributes())
+ maSchemaOptimizer.RequestType(aAttribute);
+ }
+
+ @Override public void Visit (final Element aElement)
+ {
+ final QualifiedName aName = aElement.GetTypeName();
+ if (aName == null)
+ throw new RuntimeException(
+ String.format("element '%s' has no type, defined at %s",
+ aElement.toString(),
+ aElement.GetLocation()));
+ maSchemaOptimizer.RequestType(aName);
+ }
+ @Override public void Visit (final ElementReference aElementReference)
+ {
+ Visit(aElementReference.GetReferencedElement(maSourceSchema));
+ }
+ @Override public void Visit (final Extension aExtension)
+ {
+ maSchemaOptimizer.RequestType(aExtension.GetBaseTypeName());
+ }
+ @Override public void Visit (final GroupReference aReference)
+ {
+ maSchemaOptimizer.RequestType(aReference.GetReferencedGroup(maSourceSchema));
+ }
+ @Override public void Visit (final List aList)
+ {
+ maSchemaOptimizer.RequestType(aList.GetItemType());
+ }
+ @Override public void Visit (final SimpleTypeReference aReference)
+ {
+ maSchemaOptimizer.RequestType(aReference.GetReferencedSimpleType(maSourceSchema));
+ }
+ @Override public void Visit (final Union aUnion)
+ {
+ }
+
+ @Override public void Default (final INode aNode)
+ {
+ switch (aNode.GetNodeType())
+ {
+ case All:
+ case Any:
+ case BuiltIn:
+ case Choice:
+ case ComplexContent:
+ case ComplexType:
+ case Group:
+ case List:
+ case OccurrenceIndicator:
+ case Sequence:
+ case SimpleContent:
+ case SimpleType:
+ break;
+ default:
+ throw new RuntimeException(
+ String.format("don't know how to request %s which was defined at %s",
+ aNode.toString(),
+ aNode.GetLocation()));
+ }
+ }
+
+ private final Schema maSourceSchema;
+ private final SchemaOptimizer maSchemaOptimizer;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/SchemaOptimizer.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/SchemaOptimizer.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/SchemaOptimizer.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/SchemaOptimizer.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,119 @@
+package org.apache.openoffice.ooxml.schema.model.optimize;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
+
+import org.apache.openoffice.ooxml.schema.iterator.NodeIterator;
+import org.apache.openoffice.ooxml.schema.model.base.INode;
+import org.apache.openoffice.ooxml.schema.model.base.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.NodeType;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+import org.apache.openoffice.ooxml.schema.model.complex.Element;
+import org.apache.openoffice.ooxml.schema.model.schema.Schema;
+
+public class SchemaOptimizer
+{
+ public SchemaOptimizer (final Schema aOriginalSchema)
+ {
+ maOriginalSchema = aOriginalSchema;
+ maOptimizedSchema = new Schema();
+ maTodoList = new LinkedList<>();
+ maProcessedTypes = new HashSet<>();
+
+ maRequestVisitor = new RequestVisitor(maOriginalSchema, this);
+ }
+
+
+
+
+ public Schema Run ()
+ {
+ // Copy over the top-level elements. They are the seeds in the use chain of types.
+ for (final Element aElement : maOriginalSchema.TopLevelElements.GetUnsorted())
+ maOptimizedSchema.TopLevelElements.Add(aElement);
+
+ // Seed the todo list with the types to which the top-level elements lead.
+ for (final Element aElement : maOriginalSchema.TopLevelElements.GetUnsorted())
+ RequestType(aElement.GetTypeName());
+
+ ProcessTodoList();
+
+ return maOptimizedSchema;
+ }
+
+
+
+
+ void RequestType (final QualifiedName aName)
+ {
+ final Node aNode = maOriginalSchema.GetTypeForName(aName);
+ if (aNode == null)
+ throw new RuntimeException("there is no type named '"+aName+"' in the schema");
+ else
+ RequestType(aNode);
+ }
+
+
+
+
+ void RequestType (final INode aNode)
+ {
+ if (aNode.GetNodeType() == NodeType.SimpleTypeReference)
+ System.out.println(aNode);
+ if ( ! maProcessedTypes.contains(aNode))
+ {
+ maProcessedTypes.add(aNode);
+ maTodoList.add(aNode);
+ }
+ }
+
+
+
+
+ /** Process each entry in the todo list until it is empty.
+ * Each type in it is used and inserted into the optimized schema.
+ */
+ private void ProcessTodoList ()
+ {
+ final INodeVisitor aVisitor = new ProcessTypeVisitor(
+ maOriginalSchema,
+ maOptimizedSchema,
+ this);
+ while ( ! maTodoList.isEmpty())
+ {
+ final INode aNode = maTodoList.poll();
+ aNode.AcceptVisitor(aVisitor);
+
+ // Request used namespaces.
+ final QualifiedName aName = aNode.GetName();
+ if (aName != null)
+ maOptimizedSchema.Namespaces.ProvideNamespace(aName.GetNamespaceURI(), aName.GetNamespacePrefix());
+ }
+ }
+
+
+
+
+ /** Iterate over all nodes in the given type definition.
+ * References to types are inserted into the todo list.
+ */
+ void RequestReferencedTypes (final Node aRoot)
+ {
+ for (final INode aNode : new NodeIterator(aRoot))
+ {
+ aNode.AcceptVisitor(maRequestVisitor);
+ }
+ }
+
+
+
+
+ private final Schema maOriginalSchema;
+ private final Schema maOptimizedSchema;
+ private final Queue<INode> maTodoList;
+ private final Set<INode> maProcessedTypes;
+ private final RequestVisitor maRequestVisitor;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/NamespaceMap.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/NamespaceMap.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/NamespaceMap.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/NamespaceMap.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,144 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.schema;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/** Map between namespace prefixes and URIs.
+ * While namespace URIs can have different prefixes in different schemas,
+ * we will use only one prefix in the OOXML parser. This class
+ * provides these global prefixes.
+ */
+public class NamespaceMap
+ implements Iterable<Entry<String, String>>
+{
+ public NamespaceMap ()
+ {
+ maURIToPrefixMap = new HashMap<>(maPredefinedURIToPrefixMap);
+
+ // Hack to cover the older file format.
+ maURIToPrefixMap.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a06");
+ maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/main", "a12");
+
+ maURIToPrefixMap.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp06");
+ maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/wordprocessingDrawing", "wp12");
+
+ maURIToPrefixMap.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w06");
+ maURIToPrefixMap.put("http://purl.oclc.org/ooxml/wordprocessingml/main", "w12");
+
+ maURIToPrefixMap.put("http://schemas.openxmlformats.org/drawingml/2006/picture", "dpct06");
+ maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/picture", "dpct12");
+
+ maURIToPrefixMap.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m06");
+ maURIToPrefixMap.put("http://purl.oclc.org/ooxml/officeDocument/math", "m12");
+
+ maURIToPrefixMap.put("http://purl.oclc.org/ooxml/officeDocument/relationships", "r12");
+ }
+
+
+
+
+ public void ProvideNamespace (
+ final String sNamespaceURI,
+ final String sDefaultPrefix)
+ {
+ if ( ! maURIToPrefixMap.containsKey(sNamespaceURI))
+ {
+ final String sPrefix;
+ if (sDefaultPrefix != null)
+ {
+ // Check if we can use the given prefix.
+ if (IsPrefixUsed(sDefaultPrefix))
+ {
+ // Prefix is already used. We have to create a new and unique one.
+ sPrefix = new String(new byte[]{(byte)('A'+maURIToPrefixMap.size())});
+ }
+ else
+ {
+ // Use the given prefix.
+ sPrefix = sDefaultPrefix;
+ }
+ }
+ else
+ {
+ // Namespace is used without prefix. Don't invent one.
+ // It is OK that the resulting null value is not unique.
+ sPrefix = null;
+ }
+
+ maURIToPrefixMap.put(sNamespaceURI, sPrefix);
+ }
+ }
+
+
+
+
+ public String GetNamespacePrefix (final String sURI)
+ {
+ return maURIToPrefixMap.get(sURI);
+ }
+
+
+
+
+ public Iterator<Entry<String,String>> iterator ()
+ {
+ return maURIToPrefixMap.entrySet().iterator();
+ }
+
+
+
+
+ public Object GetCount()
+ {
+ return maURIToPrefixMap.size();
+ }
+
+
+
+
+ private boolean IsPrefixUsed (final String sPrefix)
+ {
+ for (final String sUsedPrefix : maURIToPrefixMap.values())
+ {
+ if (sUsedPrefix == null)
+ continue;
+ if (sUsedPrefix.equals(sPrefix))
+ return true;
+ }
+ return false;
+ }
+
+
+
+
+ private final Map<String,String> maURIToPrefixMap;
+ private final static Map<String,String> maPredefinedURIToPrefixMap;
+ static
+ {
+ maPredefinedURIToPrefixMap = new HashMap<>();
+ maPredefinedURIToPrefixMap.put("http://www.w3.org/2001/XMLSchema", "xsd");
+ }
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/Schema.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/Schema.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/Schema.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/Schema.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,96 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.schema;
+
+import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
+import org.apache.openoffice.ooxml.schema.model.attribute.AttributeGroup;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+import org.apache.openoffice.ooxml.schema.model.complex.ComplexType;
+import org.apache.openoffice.ooxml.schema.model.complex.Element;
+import org.apache.openoffice.ooxml.schema.model.complex.Group;
+import org.apache.openoffice.ooxml.schema.model.optimize.SchemaOptimizer;
+import org.apache.openoffice.ooxml.schema.model.simple.BuiltIn;
+import org.apache.openoffice.ooxml.schema.model.simple.SimpleType;
+
+/** Representation of a set of schema files (typically one master file and the included schema filed.)
+ */
+public class Schema
+{
+ public Schema ()
+ {
+ Namespaces = new NamespaceMap();
+ ComplexTypes = new TypeContainer<>();
+ SimpleTypes = new TypeContainer<>();
+ Groups = new TypeContainer<>();
+ AttributeGroups = new TypeContainer<>();
+ Attributes = new TypeContainer<>();
+ TopLevelElements = new TypeContainer<>();
+
+ // Initialize the list of simple types with all known built ins (
+ // these are implicitly defined).
+ for (final BuiltIn aType : BuiltIn.GetTypes())
+ SimpleTypes.Add(aType);
+ }
+
+
+
+
+ public Node GetTypeForName (final QualifiedName aName)
+ {
+ final String sTypeName = aName.GetDisplayName();
+
+ if (ComplexTypes.Contains(sTypeName))
+ return ComplexTypes.Get(sTypeName);
+ else if (SimpleTypes.Contains(sTypeName))
+ return SimpleTypes.Get(sTypeName);
+ else if (Groups.Contains(sTypeName))
+ return Groups.Get(sTypeName);
+ else if (TopLevelElements.Contains(sTypeName))
+ return TopLevelElements.Get(sTypeName);
+ else
+ return null;
+ }
+
+
+
+
+ /** Create a new schema object that contains only the used types, i.e.
+ * types that are reachable via element transitions, starting with the
+ * top level elements.
+ */
+ public Schema GetOptimizedSchema ()
+ {
+ return new SchemaOptimizer(this).Run();
+ }
+
+
+
+
+ public final NamespaceMap Namespaces;
+ public final TypeContainer<ComplexType> ComplexTypes;
+ public final TypeContainer<SimpleType> SimpleTypes;
+ public final TypeContainer<Group> Groups;
+ public final TypeContainer<AttributeGroup> AttributeGroups;
+ public final TypeContainer<Attribute> Attributes;
+ public final TypeContainer<Element> TopLevelElements;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/TypeContainer.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/TypeContainer.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/TypeContainer.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/TypeContainer.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,100 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.schema;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+
+public class TypeContainer<T extends Node>
+{
+ TypeContainer ()
+ {
+ maTypes = new HashMap<>();
+ }
+
+
+
+
+ public void Add (final T aType)
+ {
+ maTypes.put(aType.GetName().GetDisplayName(), aType);
+ }
+
+
+
+
+ public T Get (final QualifiedName aName)
+ {
+ return maTypes.get(aName.GetDisplayName());
+ }
+
+
+
+
+ public T Get (final String sPrefixedName)
+ {
+ return maTypes.get(sPrefixedName);
+ }
+
+
+
+
+ public boolean Contains (final String sPrefixedName)
+ {
+ return maTypes.containsKey(sPrefixedName);
+ }
+
+
+
+
+ public int GetCount ()
+ {
+ return maTypes.size();
+ }
+
+
+
+
+ public Iterable<T> GetUnsorted ()
+ {
+ return maTypes.values();
+ }
+
+
+
+
+ public Iterable<T> GetSorted ()
+ {
+ final Set<T> aSortedItems = new TreeSet<T>(maTypes.values());
+ return aSortedItems;
+ }
+
+
+
+
+ Map<String,T> maTypes;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/BuiltIn.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/BuiltIn.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/BuiltIn.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/BuiltIn.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,146 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.simple;
+
+import java.util.Vector;
+
+import org.apache.openoffice.ooxml.schema.model.base.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.NodeType;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+
+/** Representation of built in types.
+ */
+public class BuiltIn
+ extends SimpleType
+{
+ public enum Type
+ {
+ String,
+ Token,
+ Byte,
+ UnsignedByte,
+ Short,
+ UnsignedShort,
+ Int,
+ UnsignedInt,
+ Integer,
+ Long,
+ Float,
+ Double,
+ Boolean,
+ Base64Binary,
+ DateTime,
+ AnyURI
+ }
+ public static final String XsdNamespace = "http://www.w3.org/2001/XMLSchema";
+
+
+
+
+ public static Vector<BuiltIn> GetTypes ()
+ {
+ final Vector<BuiltIn> aTypes = new Vector<>();
+ for (final Type eType : Type.values())
+ aTypes.add(new BuiltIn(eType));
+ return aTypes;
+ }
+
+
+
+
+ protected BuiltIn (
+ final Type eType)
+ {
+ super(null, GetNameForType(eType), null);
+ meType = eType;
+ }
+
+
+
+
+ @Override
+ public NodeType GetNodeType ()
+ {
+ return NodeType.BuiltIn;
+ }
+
+
+
+
+ public Type GetBuiltInType ()
+ {
+ return meType;
+ }
+
+
+
+
+ @Override
+ public void AcceptVisitor (final INodeVisitor aVisitor)
+ {
+ aVisitor.Visit(this);
+ }
+
+
+
+
+ private static QualifiedName GetNameForType (final Type eType)
+ {
+ final String sTypeName;
+ switch (eType)
+ {
+ case String: sTypeName = "string"; break;
+ case Token: sTypeName = "token"; break;
+ case Byte: sTypeName = "byte"; break;
+ case UnsignedByte: sTypeName = "unsignedByte"; break;
+ case Short: sTypeName = "short"; break;
+ case UnsignedShort: sTypeName = "unsignedShort"; break;
+ case Int: sTypeName = "int"; break;
+ case UnsignedInt: sTypeName = "unsignedInt"; break;
+ case Integer: sTypeName = "integer"; break;
+ case Long: sTypeName = "long"; break;
+ case Float: sTypeName = "float"; break;
+ case Double: sTypeName = "double"; break;
+ case Boolean: sTypeName = "boolean"; break;
+ case Base64Binary: sTypeName = "base64Binary"; break;
+ case DateTime: sTypeName = "dateTime"; break;
+ case AnyURI: sTypeName = "anyURI"; break;
+ default:
+ throw new RuntimeException();
+ }
+ return new QualifiedName(XsdNamespace, "xsd", sTypeName);
+ }
+
+
+
+
+ @Override
+ public String toString ()
+ {
+ return "builtin "+GetName().GetDisplayName();
+ }
+
+
+
+
+ private final Type meType;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/List.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/List.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/List.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/List.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,84 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.simple;
+
+import org.apache.openoffice.ooxml.schema.model.base.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.Location;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.NodeType;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+
+/** Representation of the 'list' XML schema element.
+ * It is similar to an array of objects that are all of the same simple type.
+ */
+public class List
+ extends Node
+{
+ public List (
+ final Node aParent,
+ final QualifiedName aItemType,
+ final Location aLocation)
+ {
+ super(aParent, null, aLocation);
+ maItemType = aItemType;
+ }
+
+
+
+
+ @Override
+ public NodeType GetNodeType ()
+ {
+ return NodeType.List;
+ }
+
+
+
+
+ @Override
+ public void AcceptVisitor (final INodeVisitor aVisitor)
+ {
+ aVisitor.Visit(this);
+ }
+
+
+
+
+ public QualifiedName GetItemType ()
+ {
+ return maItemType;
+ }
+
+
+
+
+ @Override
+ public String toString ()
+ {
+ return "list of "+maItemType.GetDisplayName()+" items";
+ }
+
+
+
+
+ private final QualifiedName maItemType;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/Restriction.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/Restriction.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/Restriction.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/Restriction.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,210 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.simple;
+
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import org.apache.openoffice.ooxml.schema.model.base.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.Location;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.NodeType;
+
+/** Representation of the 'restriction' XML schema element.
+ * It defines constraints on a another simple type.
+ * Examples for such restrictions are minimum and maximum values
+ * (inclusive or exclusive), patterns or length constraints of strings,
+ * sets of valid values.
+ */
+public class Restriction
+ extends Node
+{
+ public Restriction (
+ final Node aParent,
+ final String sBaseType,
+ final Location aLocation)
+ {
+ super(aParent, null, aLocation);
+ msBaseType = sBaseType;
+ maEnumerations = new TreeSet<>();
+ }
+
+
+
+ @Override
+ public void AcceptVisitor (final INodeVisitor aVisitor)
+ {
+ aVisitor.Visit(this);
+ }
+
+
+
+ @Override
+ public NodeType GetNodeType()
+ {
+ return NodeType.Restriction;
+ }
+
+
+
+
+ @Override
+ public String toString ()
+ {
+ final StringBuffer aBuffer = new StringBuffer("restriction based on ");
+ aBuffer.append(msBaseType);
+
+ if (mnMinInclusive != null)
+ {
+ aBuffer.append(",minInclusive=");
+ aBuffer.append(mnMinInclusive);
+ }
+ if (mnMinExclusive != null)
+ {
+ aBuffer.append(",minExclusive=");
+ aBuffer.append(mnMinExclusive);
+ }
+ if (mnMaxInclusive != null)
+ {
+ aBuffer.append(",maxInclusive=");
+ aBuffer.append(mnMaxInclusive);
+ }
+ if (mnMaxExclusive != null)
+ {
+ aBuffer.append(",maxExclusive=");
+ aBuffer.append(mnMaxExclusive);
+ }
+ if (mnLength != null)
+ {
+ aBuffer.append(",length=");
+ aBuffer.append(mnLength);
+ }
+ if (mnMinLength != null)
+ {
+ aBuffer.append(",minLength=");
+ aBuffer.append(mnMinLength);
+ }
+ if (mnMaxLength != null)
+ {
+ aBuffer.append(",maxLength=");
+ aBuffer.append(mnMaxLength);
+ }
+ if (maPattern != null)
+ {
+ aBuffer.append(",pattern=\"");
+ aBuffer.append(maPattern);
+ aBuffer.append('"');
+ }
+ if ( ! maEnumerations.isEmpty())
+ {
+ aBuffer.append(",enumerations");
+ aBuffer.append(maEnumerations);
+ }
+ return aBuffer.toString();
+ }
+
+
+
+ public void AddEnumeration (final String sValue)
+ {
+ maEnumerations.add(sValue);
+ }
+
+
+
+
+ public void SetMinInclusive (final String sValue)
+ {
+ mnMinInclusive = Double.parseDouble(sValue);
+ }
+
+
+
+
+ public void SetMinExclusive (final String sValue)
+ {
+ mnMinExclusive = Double.parseDouble(sValue);
+ }
+
+
+
+
+ public void SetMaxInclusive (final String sValue)
+ {
+ mnMaxInclusive = Double.parseDouble(sValue);
+ }
+
+
+
+
+ public void SetMaxExclusive (final String sValue)
+ {
+ mnMaxExclusive = Double.parseDouble(sValue);
+ }
+
+
+
+
+ public void SetLength (final String sValue)
+ {
+ mnLength = Integer.parseInt(sValue);
+ }
+
+
+
+
+ public void SetMinLength (final String sValue)
+ {
+ mnMinLength = Integer.parseInt(sValue);
+ }
+
+
+
+
+ public void SetMaxLength (final String sValue)
+ {
+ mnMaxLength = Integer.parseInt(sValue);
+ }
+
+
+
+
+ public void SetPattern (final String sValue)
+ {
+ maPattern = Pattern.compile(sValue);
+ }
+
+
+
+
+ private final String msBaseType;
+ private final Set<String> maEnumerations;
+ private Double mnMinInclusive;
+ private Double mnMinExclusive;
+ private Double mnMaxInclusive;
+ private Double mnMaxExclusive;
+ private Integer mnLength;
+ private Integer mnMinLength;
+ private Integer mnMaxLength;
+ private Pattern maPattern;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleContent.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleContent.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleContent.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleContent.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,56 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.simple;
+
+import org.apache.openoffice.ooxml.schema.model.base.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.Location;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.NodeType;
+
+public class SimpleContent
+ extends Node
+{
+ public SimpleContent (
+ final Node aParent,
+ final Location aLocation)
+ {
+ super(aParent, null, aLocation);
+ }
+
+
+
+
+ @Override
+ public void AcceptVisitor (final INodeVisitor aVisitor)
+ {
+ aVisitor.Visit(this);
+ }
+
+
+
+
+ @Override
+ public NodeType GetNodeType()
+ {
+ return NodeType.SimpleContent;
+ }
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleType.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleType.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleType.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleType.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,121 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.simple;
+
+import org.apache.openoffice.ooxml.schema.model.base.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.Location;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.NodeType;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+
+/** Representation of the 'simpleType' XML schema element.
+ * Simple types are used for attributes or the text of elements.
+ */
+public class SimpleType
+ extends Node
+{
+ public SimpleType (
+ final Node aParent,
+ final QualifiedName aName,
+ final Location aLocation)
+ {
+ super(aParent, aName, aLocation);
+ maRestriction = null;
+ maFinalValues = null;
+ }
+
+
+
+
+ @Override
+ public NodeType GetNodeType ()
+ {
+ return NodeType.SimpleType;
+ }
+
+
+
+
+ public void SetRestriction (final Restriction aRestriction)
+ {
+ assert(maRestriction==null);
+ maRestriction = aRestriction;
+ }
+
+
+
+
+ public Restriction GetRestriction ()
+ {
+ return maRestriction;
+ }
+
+
+
+
+ public void SetFinal (final String[] aFinalValues)
+ {
+ maFinalValues = aFinalValues;
+ }
+
+
+
+
+ public boolean IsFinal (final String sCatgery)
+ {
+ if (maFinalValues != null)
+ {
+ for (final String sFinal : maFinalValues)
+ {
+ if (sFinal.equals(sCatgery))
+ return true;
+ else if (sFinal.equals("#all"))
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+
+
+ @Override
+ public void AcceptVisitor (final INodeVisitor aVisitor)
+ {
+ aVisitor.Visit(this);
+ }
+
+
+
+
+ @Override
+ public String toString ()
+ {
+ return "simple type "+GetName().GetDisplayName();
+ }
+
+
+
+
+ private Restriction maRestriction;
+ private String[] maFinalValues;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleTypeReference.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleTypeReference.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleTypeReference.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/SimpleTypeReference.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,107 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.simple;
+
+import org.apache.openoffice.ooxml.schema.model.base.INode;
+import org.apache.openoffice.ooxml.schema.model.base.INodeReference;
+import org.apache.openoffice.ooxml.schema.model.base.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.Location;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.NodeType;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+import org.apache.openoffice.ooxml.schema.model.schema.Schema;
+
+public class SimpleTypeReference
+ extends Node
+ implements INodeReference
+{
+ public SimpleTypeReference (
+ final Node aParent,
+ final QualifiedName aReferencedTypeName,
+ final Location aLocation)
+ {
+ super(aParent, null, aLocation);
+ maReferencedTypeName = aReferencedTypeName;
+ }
+
+
+
+
+ public SimpleType GetReferencedSimpleType (final Schema aSchema)
+ {
+ final Node aType = aSchema.GetTypeForName(maReferencedTypeName);
+ if (aType == null)
+ throw new RuntimeException("there is no type named '"+maReferencedTypeName+"' in the schema");
+ else if (aType.GetNodeType()!=NodeType.SimpleType && aType.GetNodeType()!=NodeType.BuiltIn)
+ throw new RuntimeException("name '"+maReferencedTypeName+"' references a "+aType.GetNodeType()+" not a simple type or builtin");
+ else
+ return (SimpleType)aType;
+ }
+
+
+
+
+ @Override
+ public INode GetReferencedNode (final Schema aSchema)
+ {
+ return GetReferencedSimpleType(aSchema);
+ }
+
+
+
+
+ public QualifiedName GetReferencedTypeName()
+ {
+ return maReferencedTypeName;
+ }
+
+
+
+
+ @Override
+ public void AcceptVisitor (final INodeVisitor aVisitor)
+ {
+ aVisitor.Visit(this);
+ }
+
+
+
+
+ @Override
+ public NodeType GetNodeType ()
+ {
+ return NodeType.SimpleTypeReference;
+ }
+
+
+
+ @Override
+ public String toString ()
+ {
+ return "reference to simple type "+maReferencedTypeName;
+ }
+
+
+
+
+ private final QualifiedName maReferencedTypeName;
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/Union.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/Union.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/Union.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/simple/Union.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,68 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.model.simple;
+
+import org.apache.openoffice.ooxml.schema.model.base.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.Location;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.NodeType;
+
+/** Representation of the 'union' XML schema element.
+ * Its set of valid values is the union of all of its children.
+ */
+public class Union
+ extends Node
+{
+ public Union (
+ final Node aParent,
+ final Location aLocation)
+ {
+ super(aParent, null, aLocation);
+ }
+
+
+
+
+ @Override
+ public NodeType GetNodeType ()
+ {
+ return NodeType.Union;
+ }
+
+
+
+
+ @Override
+ public void AcceptVisitor (final INodeVisitor aVisitor)
+ {
+ aVisitor.Visit(this);
+ }
+
+
+
+
+ @Override
+ public String toString ()
+ {
+ return "union";
+ }
+}
Added: openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/parser/SchemaParser.java
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/parser/SchemaParser.java?rev=1599430&view=auto
==============================================================================
--- openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/parser/SchemaParser.java (added)
+++ openoffice/trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/parser/SchemaParser.java Tue Jun 3 06:57:13 2014
@@ -0,0 +1,1185 @@
+/**************************************************************
+*
+* 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.openoffice.ooxml.schema.parser;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
+import org.apache.openoffice.ooxml.schema.model.attribute.AttributeGroup;
+import org.apache.openoffice.ooxml.schema.model.attribute.AttributeGroupReference;
+import org.apache.openoffice.ooxml.schema.model.attribute.AttributeReference;
+import org.apache.openoffice.ooxml.schema.model.base.INode;
+import org.apache.openoffice.ooxml.schema.model.base.Location;
+import org.apache.openoffice.ooxml.schema.model.base.Node;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+import org.apache.openoffice.ooxml.schema.model.complex.All;
+import org.apache.openoffice.ooxml.schema.model.complex.Any;
+import org.apache.openoffice.ooxml.schema.model.complex.Choice;
+import org.apache.openoffice.ooxml.schema.model.complex.ComplexContent;
+import org.apache.openoffice.ooxml.schema.model.complex.ComplexType;
+import org.apache.openoffice.ooxml.schema.model.complex.Element;
+import org.apache.openoffice.ooxml.schema.model.complex.ElementReference;
+import org.apache.openoffice.ooxml.schema.model.complex.Extension;
+import org.apache.openoffice.ooxml.schema.model.complex.Group;
+import org.apache.openoffice.ooxml.schema.model.complex.GroupReference;
+import org.apache.openoffice.ooxml.schema.model.complex.OccurrenceIndicator;
+import org.apache.openoffice.ooxml.schema.model.complex.Sequence;
+import org.apache.openoffice.ooxml.schema.model.schema.Schema;
+import org.apache.openoffice.ooxml.schema.model.simple.List;
+import org.apache.openoffice.ooxml.schema.model.simple.Restriction;
+import org.apache.openoffice.ooxml.schema.model.simple.SimpleContent;
+import org.apache.openoffice.ooxml.schema.model.simple.SimpleType;
+import org.apache.openoffice.ooxml.schema.model.simple.SimpleTypeReference;
+import org.apache.openoffice.ooxml.schema.model.simple.Union;
+
+
+/** Parser for single schema file.
+ * Imports and includes of other schema files are stored and can be retrieved
+ * by calling GetImportedSchemas().
+ *
+ * Typical usage:
+ * 1) Create SchemaParser for top-level schema file.
+ * 2) Call Parse().
+ * 3) Repeat the same recursively for all imported schemas (as returned by
+ * GetImportedSchemas()).
+ *
+ * All top level types (complex types, simple types, elements, etc.) are
+ * stored in the given Schema object.
+ */
+public class SchemaParser
+{
+ public SchemaParser (
+ final File aSchemaFile,
+ final Schema aSchema)
+ {
+ maSchema = aSchema;
+ maReader = GetStreamReader(aSchemaFile);
+ msBasename = aSchemaFile.getName();
+ maDirectory = aSchemaFile.getParentFile();
+ maLocalNamespaceMap = new HashMap<>();
+ maImportedSchemas = new Vector<>();
+ maLastLocation = null;
+ }
+
+
+
+
+ /** Parse the schema file.
+ * @return
+ * Return false if there is any error.
+ * @throws XMLStreamException
+ */
+ public void Parse ()
+ throws XMLStreamException
+ {
+ if (maReader == null)
+ return;
+
+ while (maReader.hasNext())
+ {
+ final int nCode = maReader.next();
+ switch (nCode)
+ {
+ case XMLStreamReader.START_ELEMENT:
+ if (maReader.getLocalName().equals("schema"))
+ {
+ ProcessNamespaceDefinitions();
+ ParseSchema();
+
+ maLastLocation = maReader.getLocation();
+ }
+ else
+ {
+ throw CreateErrorException("expecting top level element to be 'schema'");
+ }
+ break;
+
+ case XMLStreamReader.END_DOCUMENT:
+ return;
+
+ default:
+ throw CreateErrorException("unexpected XML event %d", nCode);
+ }
+ }
+ }
+
+
+
+
+ public Iterable<File> GetImportedSchemaFilenames ()
+ {
+ return maImportedSchemas;
+ }
+
+
+
+
+ public int GetLineCount ()
+ {
+ if (maLastLocation != null)
+ return maLastLocation.getLineNumber();
+ else
+ return 0;
+ }
+
+
+
+
+ public int GetByteCount ()
+ {
+ if (maLastLocation != null)
+ return maLastLocation.getCharacterOffset();
+ else
+ return 0;
+ }
+
+
+
+
+ /** Process the namespace definitions in the outer 'schema' element.
+ */
+ private void ProcessNamespaceDefinitions ()
+ {
+ for (int nIndex=0; nIndex<maReader.getNamespaceCount(); ++nIndex)
+ {
+ final String sPrefix = maReader.getNamespacePrefix(nIndex);
+ final String sURI = maReader.getNamespaceURI(nIndex);
+ maLocalNamespaceMap.put(sPrefix, sURI);
+ maSchema.Namespaces.ProvideNamespace(sURI, sPrefix);
+ }
+ msTargetNamespace = GetAttributeValue("targetNamespace");
+ maLocalNamespaceMap.put(null, msTargetNamespace);
+ maSchema.Namespaces.ProvideNamespace(msTargetNamespace, null);
+ }
+
+
+
+
+ private void ParseSchema ()
+ throws XMLStreamException
+ {
+ while (true)
+ {
+ switch (Next())
+ {
+ case XMLStreamReader.START_ELEMENT:
+ ProcessTopLevelStartElement();
+ break;
+
+ case XMLStreamReader.END_ELEMENT:
+ return;
+
+ default:
+ throw CreateErrorException("unexpected event (expteced START_ELEMENT): %d", maReader.getEventType());
+ }
+ }
+ }
+
+
+
+
+ private void ProcessTopLevelStartElement ()
+ throws XMLStreamException
+ {
+ assert(GetAttributeValue("minOccurs") == null);
+ assert(GetAttributeValue("maxOccurs") == null);
+
+ switch (maReader.getLocalName())
+ {
+ case "attribute":
+ maSchema.Attributes.Add(ParseAttribute());
+ break;
+
+ case "attributeGroup":
+ maSchema.AttributeGroups.Add(ParseAttributeGroup());
+ break;
+
+ case "complexType":
+ maSchema.ComplexTypes.Add(ParseComplexType());
+ break;
+
+ case "element":
+ maSchema.TopLevelElements.Add(ParseElement(null));
+ break;
+
+ case "group":
+ maSchema.Groups.Add(ParseGroup(null));
+ break;
+
+ case "import":
+ ParseImport();
+ break;
+
+ case "include":
+ ParseInclude();
+ break;
+
+ case "simpleType":
+ maSchema.SimpleTypes.Add(ParseSimpleType(null));
+ break;
+
+ default:
+ throw CreateErrorException("unexpected top level element %s", maReader.getLocalName());
+ }
+ }
+
+
+
+
+ private void ProcessStartElement (final Node aParent)
+ throws XMLStreamException
+ {
+ final String sMinimumOccurrence = GetOptionalAttributeValue("minOccurs", "1");
+ final String sMaximumOccurrence = GetOptionalAttributeValue("maxOccurs", "1");
+
+ final Node aLocalParent;
+ if ( ! (sMinimumOccurrence.equals("1") && sMaximumOccurrence.equals("1")))
+ {
+ // Occurrence does not only have default values (min=max=1).
+ // Have to create an intermediate node for the occurrence indicator.
+ final OccurrenceIndicator aIndicator = new OccurrenceIndicator(
+ aParent,
+ sMinimumOccurrence,
+ sMaximumOccurrence,
+ GetLocation());
+ aParent.AddChild(aIndicator);
+ aLocalParent = aIndicator;
+ }
+ else
+ aLocalParent = aParent;
+
+ switch (maReader.getLocalName())
+ {
+ case "all":
+ aLocalParent.AddChild(ParseAll(aLocalParent));
+ break;
+
+ case "any":
+ aLocalParent.AddChild(ParseAny(aLocalParent));
+ break;
+
+ case "attribute":
+ aLocalParent.AddAttribute(ParseAttributeOrReference());
+ break;
+
+ case "attributeGroup":
+ aLocalParent.AddAttribute(ParseAttributeGroupOrReference());
+ break;
+
+ case "choice":
+ aLocalParent.AddChild(ParseChoice(aLocalParent));
+ break;
+
+ case "complexContent":
+ aLocalParent.AddChild(ParseComplexContent(aLocalParent));
+ break;
+
+ case "element":
+ aLocalParent.AddChild(ParseElementOrReference(aLocalParent));
+ break;
+
+ case "extension":
+ aLocalParent.AddChild(ParseExtension(aLocalParent));
+ break;
+
+ case "group":
+ aLocalParent.AddChild(ParseGroupOrReference(aLocalParent));
+ break;
+
+ case "list":
+ aLocalParent.AddChild(ParseList(aLocalParent));
+ break;
+
+ case "sequence":
+ aLocalParent.AddChild(ParseSequence(aLocalParent));
+ break;
+
+ case "simpleContent":
+ aLocalParent.AddChild(ParseSimpleContent(aLocalParent));
+ break;
+
+ default:
+ throw CreateErrorException("unsupported content type %s", maReader.getLocalName());
+ }
+ }
+
+
+
+
+ private void IgnoreAnnotation ()
+ throws XMLStreamException
+ {
+ IgnoreContent();
+ }
+
+
+
+
+ private void IgnoreContent ()
+ throws XMLStreamException
+ {
+ while(true)
+ {
+ switch(maReader.next())
+ {
+ case XMLStreamReader.START_ELEMENT:
+ IgnoreContent();
+ break;
+
+ case XMLStreamReader.END_ELEMENT:
+ return;
+
+ case XMLStreamReader.COMMENT:
+ case XMLStreamReader.CHARACTERS:
+ break;
+
+ default:
+ throw CreateErrorException(
+ "unexpected XML event %d while ignoring content",
+ maReader.getEventType());
+ }
+ }
+ }
+
+
+
+
+ private All ParseAll (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs"));
+
+ final All aAll = new All(aParent, GetLocation());
+ ParseContent(aAll);
+ return aAll;
+ }
+
+
+
+
+ private Any ParseAny (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs", "namespace", "processContents"));
+
+ final Any aAny = new Any(aParent, GetAttributeValue("processContents"), GetLocation());
+ ExpectEndElement("ParseAny");
+ return aAny;
+ }
+
+
+
+
+ private AttributeGroup ParseAttributeGroup ()
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("name"));
+
+ final AttributeGroup aGroup = new AttributeGroup(GetOptionalQualifiedName("name"), GetLocation());
+
+ while (true)
+ {
+ switch (Next())
+ {
+ case XMLStreamReader.START_ELEMENT:
+ if ( ! maReader.getLocalName().equals("attribute"))
+ throw CreateErrorException(
+ "attributeGroup expects element 'attribute' but got %s",
+ maReader.getLocalName());
+ else
+ aGroup.AddAttribute(ParseAttributeOrReference());
+ break;
+
+ case XMLStreamReader.END_ELEMENT:
+ return aGroup;
+
+ default:
+ throw CreateErrorException(
+ "unexpected event when parsing attributeGroup: %d",
+ maReader.getEventType());
+ }
+ }
+ }
+
+
+
+
+ private INode ParseAttributeGroupOrReference ()
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("ref"));
+
+ final INode aGroup;
+ if (GetAttributeValue("schemaLocation") != null)
+ {
+ aGroup = ParseAttributeGroup();
+ }
+ else
+ {
+ aGroup = new AttributeGroupReference(
+ CreateQualifiedName(
+ GetAttributeValue("ref")),
+ GetLocation());
+ ExpectEndElement("attribute group or reference");
+ }
+ return aGroup;
+ }
+
+
+
+
+ private INode ParseAttributeOrReference ()
+ throws XMLStreamException
+ {
+ final INode aAttribute;
+ if (GetAttributeValue("name") != null)
+ {
+ aAttribute = ParseAttribute();
+ }
+ else
+ {
+ assert(HasOnlyAttributes("default", "fixed", "ref", "use"));
+
+ aAttribute = new AttributeReference(
+ GetQualifiedName("ref"),
+ GetOptionalAttributeValue("use", "optional"),
+ GetOptionalAttributeValue("default", null),
+ GetOptionalAttributeValue("fixed", null),
+ GetLocation());
+ ExpectEndElement("attribute reference");
+ }
+ return aAttribute;
+ }
+
+
+
+
+ private Attribute ParseAttribute ()
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("default", "fixed", "name", "type", "use"));
+
+ final Attribute aAttribute = new Attribute(
+ GetQualifiedName("name"),
+ GetQualifiedName("type"),
+ GetOptionalAttributeValue("use", "optional"),
+ GetOptionalAttributeValue("default", null),
+ GetOptionalAttributeValue("fixed", null),
+ GetLocation());
+ ExpectEndElement("attribute");
+
+ return aAttribute;
+ }
+
+
+
+ private Choice ParseChoice (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs"));
+
+ final Choice aChoice = new Choice(aParent, GetLocation());
+ ParseContent(aChoice);
+ return aChoice;
+ }
+
+
+
+
+ private ComplexContent ParseComplexContent (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs"));
+
+ final ComplexContent aNode = new ComplexContent(aParent, GetLocation());
+ ParseContent(aNode);
+ return aNode;
+ }
+
+
+
+
+ private ComplexType ParseComplexType ()
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("mixed", "name"));
+
+ final ComplexType aComplexType = new ComplexType(
+ null,
+ GetQualifiedName("name"),
+ GetLocation());
+
+ ParseContent(aComplexType);
+
+ return aComplexType;
+ }
+
+
+
+
+ private Element ParseElement (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs", "name", "type"));
+
+ final Element aElement = new Element(
+ aParent,
+ GetQualifiedName("name"),
+ GetQualifiedName("type"),
+ GetLocation());
+
+ ExpectEndElement("element");
+
+ return aElement;
+ }
+
+
+
+
+ private Element ParseElementOrReference (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs", "name", "ref", "type"));
+
+ final Element aElement;
+ final String sName = GetOptionalAttributeValue("name", null);
+ if (sName != null)
+ {
+ aElement = ParseElement(aParent);
+ }
+ else
+ {
+ final String sElementReference = GetOptionalAttributeValue("ref", null);
+ if (sElementReference != null)
+ {
+ ExpectEndElement("element reference");
+ aElement = new ElementReference(
+ aParent,
+ CreateQualifiedName(sElementReference),
+ GetLocation());
+ }
+ else
+ {
+ throw CreateErrorException("element has no name and no ref");
+ }
+ }
+ return aElement;
+ }
+
+
+
+
+ private Extension ParseExtension (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("base", "minOccurs", "maxOccurs"));
+
+ final Extension aNode = new Extension(
+ aParent,
+ CreateQualifiedName(GetAttributeValue("base")),
+ GetLocation());
+ ParseContent(aNode);
+ return aNode;
+ }
+
+
+
+
+ private Group ParseGroup (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("name"));
+
+ final Group aGroup = new Group(
+ aParent,
+ GetQualifiedName("name"),
+ GetLocation());
+ ParseContent(aGroup);
+ return aGroup;
+ }
+
+
+
+
+ private Node ParseGroupOrReference (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs", "name", "ref"));
+
+ final Node aGroup;
+ final String sName = GetOptionalAttributeValue("name", null);
+ if (sName != null)
+ {
+ aGroup = ParseGroup(aParent);
+ }
+ else
+ {
+ final String sGroupReference = GetOptionalAttributeValue("ref", null);
+ if (sGroupReference != null)
+ {
+ ExpectEndElement("group reference");
+ aGroup = new GroupReference(
+ aParent,
+ CreateQualifiedName(sGroupReference),
+ GetLocation());
+ }
+ else
+ {
+ throw CreateErrorException("group has no name and no ref");
+ }
+ }
+ return aGroup;
+ }
+
+
+
+
+ private Restriction ParseRestriction (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("base", "value"));
+
+ final Restriction aRestriction = new Restriction(
+ aParent,
+ GetAttributeValue("base"),
+ GetLocation());
+
+ while (true)
+ {
+ switch (Next())
+ {
+ case XMLStreamReader.START_ELEMENT:
+ final String sValue = GetAttributeValue("value");
+ switch (maReader.getLocalName())
+ {
+ case "enumeration":
+ aRestriction.AddEnumeration(sValue);
+ break;
+
+ case "minInclusive":
+ aRestriction.SetMinInclusive(sValue);
+ break;
+
+ case "minExclusive":
+ aRestriction.SetMinExclusive(sValue);
+ break;
+
+ case "maxInclusive":
+ aRestriction.SetMaxInclusive(sValue);
+ break;
+
+ case "maxExclusive":
+ aRestriction.SetMaxExclusive(sValue);
+ break;
+
+ case "length":
+ aRestriction.SetLength(sValue);
+ break;
+
+ case "minLength":
+ aRestriction.SetMinLength(sValue);
+ break;
+
+ case "maxLength":
+ aRestriction.SetMaxLength(sValue);
+ break;
+
+ case "pattern":
+ aRestriction.SetPattern(sValue);
+ break;
+
+ default:
+ throw CreateErrorException("unsupported restriction type "+maReader.getLocalName());
+ }
+ ExpectEndElement("restriction");
+ break;
+
+ case XMLStreamReader.END_ELEMENT:
+ return aRestriction;
+
+ default:
+ throw CreateErrorException("unexpected XML event while parsing restrictions: %d", maReader.getEventType());
+ }
+ }
+ }
+
+
+
+
+ private List ParseList (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("itemType"));
+
+ final List aList = new List(
+ aParent,
+ GetQualifiedName("itemType"),
+ GetLocation());
+ ExpectEndElement("list");
+ return aList;
+ }
+
+
+
+
+ private Sequence ParseSequence (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs", "name"));
+
+ final Sequence aSequence = new Sequence(
+ aParent,
+ GetOptionalQualifiedName("name"),
+ GetLocation());
+ ParseContent(aSequence);
+ return aSequence;
+ }
+
+
+
+
+ private SimpleContent ParseSimpleContent (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("minOccurs", "maxOccurs"));
+
+ final SimpleContent aSimpleContent = new SimpleContent(
+ aParent,
+ GetLocation());
+ ParseContent(aSimpleContent);
+ return aSimpleContent;
+ }
+
+
+
+
+ private SimpleType ParseSimpleType (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("final", "name"));
+
+ final SimpleType aType = new SimpleType(
+ aParent,
+ GetQualifiedName("name"),
+ GetLocation());
+ final String sFinalValue = GetOptionalAttributeValue("final", null);
+ if (sFinalValue != null)
+ aType.SetFinal(sFinalValue.split("\\s+"));
+
+ while (true)
+ {
+ switch (Next())
+ {
+ case XMLStreamReader.START_ELEMENT:
+ switch(maReader.getLocalName())
+ {
+ case "list":
+ aType.AddChild(ParseList(aType));
+ break;
+
+ case "restriction":
+ aType.SetRestriction(ParseRestriction(aType));
+ break;
+
+ case "union":
+ aType.AddChild(ParseUnion(aType));
+ break;
+
+ default:
+ throw CreateErrorException("unsupported simple type part %s", maReader.getLocalName());
+ }
+ break;
+
+ case XMLStreamReader.END_ELEMENT:
+ return aType;
+
+ default:
+ throw CreateErrorException("unexpected XML event in ParseSimpleType: %s", maReader.getEventType());
+ }
+ }
+ }
+
+
+
+
+ private Union ParseUnion (final Node aParent)
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("memberTypes"));
+
+ final Union aUnion = new Union(
+ aParent,
+ GetLocation());
+ final String[] aMemberTypes = GetAttributeValue("memberTypes").split("\\s+");
+ for (int nIndex=0; nIndex<aMemberTypes.length; ++nIndex)
+ aUnion.AddChild(
+ new SimpleTypeReference(
+ aUnion,
+ CreateQualifiedName(aMemberTypes[nIndex]),
+ GetLocation()));
+
+ ParseContent(aUnion);
+
+ return aUnion;
+ }
+
+
+ private void ParseContent (final Node aParent)
+ throws XMLStreamException
+ {
+ while(true)
+ {
+ switch(Next())
+ {
+ case XMLStreamReader.START_ELEMENT:
+ ProcessStartElement(aParent);
+ break;
+
+ case XMLStreamReader.END_ELEMENT:
+ return;
+
+ default:
+ throw CreateErrorException(
+ "unexpected XML event %d while parsing content of %s",
+ maReader.getEventType(),
+ aParent.toString());
+ }
+ }
+ }
+
+
+
+
+ private void ParseImport ()
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("id", "namespace", "schemaLocation"));
+
+ final String sFilename = GetOptionalAttributeValue("schemaLocation", null);
+ if (sFilename == null)
+ {
+ final String sNamespaceName = GetAttributeValue("namespace");
+ if (sNamespaceName.equals(XmlNamespace.NamespaceURI))
+ {
+ XmlNamespace.Apply(maSchema);
+ maLocalNamespaceMap.put(XmlNamespace.NamespacePrefix, XmlNamespace.NamespaceURI);
+ }
+ else
+ throw CreateErrorException("invalid import");
+ }
+ else
+ {
+ maImportedSchemas.add(new File(maDirectory, sFilename));
+ }
+
+ ExpectEndElement("import");
+ }
+
+
+
+
+ private void ParseInclude ()
+ throws XMLStreamException
+ {
+ assert(HasOnlyAttributes("id", "schemaLocation"));
+
+ final String sFilename = GetOptionalAttributeValue("schemaLocation", null);
+ if (sFilename == null)
+ {
+ throw CreateErrorException("invalid include");
+ }
+ else
+ {
+ maImportedSchemas.add(new File(maDirectory, sFilename));
+ }
+
+ ExpectEndElement("include");
+ }
+
+
+
+
+ private void ExpectEndElement (final String sCaller)
+ throws XMLStreamException
+ {
+ final int nNextEvent = Next();
+ if (nNextEvent != XMLStreamReader.END_ELEMENT)
+ throw CreateErrorException("expected END_ELEMENT of %s but got %s",
+ sCaller,
+ nNextEvent);
+ }
+
+
+
+
+ /** Return the next relevant token from the XML stream.
+ * Ignores comments.
+ * @return
+ * Returns the event code of the next relevant XML event or END_DOCUMENT when the end of the file has been reached.
+ */
+ private int Next ()
+ throws XMLStreamException
+ {
+ while (maReader.hasNext())
+ {
+ switch (maReader.next())
+ {
+ case XMLStreamReader.COMMENT:
+ // Ignore comments.
+ break;
+
+ case XMLStreamReader.CHARACTERS:
+ // Ignore whitespace.
+ if (maReader.getText().matches("^\\s+$"))
+ break;
+ else
+ {
+ // Character events are not expected in schema files
+ // and therefore not supported.
+ // Alternatively, they could easily be ignored.
+ throw CreateErrorException("unexpected CHARACTERS event with text [%s]", maReader.getText());
+ }
+
+ case XMLStreamReader.START_ELEMENT:
+ switch (maReader.getLocalName())
+ {
+ case "annotation":
+ IgnoreAnnotation();
+ break;
+ case "unique":
+ // Not supported.
+ IgnoreContent();
+ break;
+ default:
+ return XMLStreamReader.START_ELEMENT;
+ }
+ break;
+
+ default:
+ return maReader.getEventType();
+ }
+ }
+ return XMLStreamReader.END_DOCUMENT;
+ }
+
+
+
+
+ private String GetAttributeValue (final String sAttributeLocalName)
+ {
+ return maReader.getAttributeValue(null, sAttributeLocalName);
+ }
+
+
+
+
+ private String GetOptionalAttributeValue (
+ final String sAttributeLocalName,
+ final String sDefaultValue)
+ {
+ final String sValue = maReader.getAttributeValue(null, sAttributeLocalName);
+ if (sValue == null)
+ return sDefaultValue;
+ else
+ return sValue;
+ }
+
+
+
+
+ /** Read the specified attribute and return its value as QualifiedName object.
+ */
+ private QualifiedName GetQualifiedName (final String sAttributeLocalName)
+ {
+ final String sName = maReader.getAttributeValue(null, sAttributeLocalName);
+ if (sName == null)
+ throw CreateErrorException(
+ "did not find a qualified name as value of attribute '%s' at %s:%s",
+ sAttributeLocalName,
+ msBasename,
+ maReader.getLocation());
+ else
+ return CreateQualifiedName(sName);
+ }
+
+
+
+
+ private QualifiedName GetOptionalQualifiedName (final String sAttributeLocalName)
+ {
+ final String sName = maReader.getAttributeValue(null, sAttributeLocalName);
+ if (sName == null)
+ return null;
+ else
+ return CreateQualifiedName(sName);
+ }
+
+
+
+
+ /** Create a QualifiedName object from the given string.
+ * @param sName
+ * May or may not contain a namespace prefix (separated from the name
+ * by a colon).
+ */
+ private QualifiedName CreateQualifiedName (final String sName)
+ {
+ final String[] aParts = sName.split(":");
+ final String sNamespaceURL;
+ final String sLocalPart;
+ switch (aParts.length)
+ {
+ case 1:
+ // sName only consists of a local part.
+ // Set the namespace URL to that of the default namespace.
+ sNamespaceURL = maLocalNamespaceMap.get(null);
+ sLocalPart = aParts[0];
+ break;
+
+ case 2:
+ // sName is of the form prefix:local.
+ sNamespaceURL = maLocalNamespaceMap.get(aParts[0]);
+ sLocalPart = aParts[1];
+ break;
+
+ default:
+ throw new RuntimeException(
+ "the string '"+sName+"' can not be transformed into a qualified name");
+ }
+ if (sNamespaceURL == null)
+ throw CreateErrorException("can not determine namespace for '%s'", sName);
+ // Transform the local namespace prefix into a global namespace prefix
+ // (different schema files can use different prefixes for the same
+ // namespace URI).
+ final String sGlobalNamespacePrefix = maSchema.Namespaces.GetNamespacePrefix(sNamespaceURL);
+ return new QualifiedName(
+ sNamespaceURL,
+ sGlobalNamespacePrefix,
+ sLocalPart);
+ }
+
+
+
+
+ /** Create an XMLStreamReader for the given file.
+ * Returns null when there is an error.
+ */
+ private static XMLStreamReader GetStreamReader (final File aSchemaFile)
+ {
+ final XMLInputFactory aFactory = (XMLInputFactory)XMLInputFactory.newInstance();
+ aFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
+ aFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+ aFactory.setProperty(XMLInputFactory.IS_COALESCING, false);
+
+ try
+ {
+ return aFactory.createXMLStreamReader(
+ aSchemaFile.getName(),
+ new FileInputStream(aSchemaFile));
+ }
+ catch (Exception aException)
+ {
+ aException.printStackTrace();
+ return null;
+ }
+ }
+
+
+
+
+ private RuntimeException CreateErrorException (
+ final String sFormat,
+ final Object ... aArgumentList)
+ {
+ return new RuntimeException(String.format(sFormat, aArgumentList)
+ + String.format(" in %s at L%dC%dP%d",
+ msBasename,
+ maReader.getLocation().getLineNumber(),
+ maReader.getLocation().getColumnNumber(),
+ maReader.getLocation().getCharacterOffset()));
+ }
+
+
+
+
+ /** This predicate is only used for debugging to assert
+ * that no unsupported attributes are present.
+ * If there where then the parser has to be extended.
+ */
+ private boolean HasOnlyAttributes (final String ... aAttributeNameList)
+ {
+ for (int nIndex=0,nCount=maReader.getAttributeCount(); nIndex<nCount; ++nIndex)
+ {
+ final String sAttributeName = maReader.getAttributeLocalName(nIndex);
+ boolean bFound = false;
+ for (final String sName : aAttributeNameList)
+ if (sAttributeName.equals(sName))
+ {
+ bFound = true;
+ break;
+ }
+ if ( ! bFound)
+ {
+ // Attribute name was not found in the given list.
+ System.err.printf("attribute '%s' is not handled\n", sAttributeName);
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+
+
+ private Location GetLocation ()
+ {
+ final javax.xml.stream.Location aLocation = maReader.getLocation();
+ return new Location(
+ msBasename,
+ aLocation.getLineNumber(),
+ aLocation.getColumnNumber(),
+ aLocation.getCharacterOffset());
+ }
+
+
+
+
+ private final Schema maSchema;
+ private final XMLStreamReader maReader;
+ private final String msBasename;
+ private final File maDirectory;
+ private String msTargetNamespace;
+ /// Map of namespace prefix to URI, local to the currently read schema file.
+ private final Map<String,String> maLocalNamespaceMap;
+ /// The names of other schema files referenced by import elements.
+ private final Vector<File> maImportedSchemas;
+ /// Some values for tracking the number of read bytes and lines.
+ private javax.xml.stream.Location maLastLocation;
+}