[Libreoffice-commits] core.git: Branch 'aoo/trunk' - ooxml/source
Andre Fischer
af at apache.org
Thu Jun 12 01:07:40 PDT 2014
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AcceptingStateTable.java | 9
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeDescriptor.java | 112 +
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeManager.java | 178 ++
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeProvider.java | 48
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NameMap.java | 20
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NamespaceMap.java | 52
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/OOXMLParser.java | 68
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/ParseTableReader.java | 5
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/SkipStateTable.java | 9
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/StateMachine.java | 118 +
ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/TransitionTable.java | 23
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/SchemaReader.java | 2
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/Test.java | 1
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/CreatorBase.java | 124 +
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/DFACreator.java | 6
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomaton.java | 17
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomatonContainer.java | 13
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/HopcroftMinimizer.java | 6
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/NonValidatingCreator.java | 70
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreator.java | 727 +++++++++-
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreatorVisitor.java | 646 --------
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/ParserTablesGenerator.java | 124 +
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/iterator/AttributeIterator.java | 2
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/iterator/AttributeNodeIterator.java | 112 +
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/attribute/Attribute.java | 8
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/attribute/AttributeBase.java | 28
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/attribute/AttributeReference.java | 15
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/CopyVisitor.java | 111 +
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/ProcessTypeVisitor.java | 110 -
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/RequestVisitor.java | 43
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/optimize/SchemaOptimizer.java | 93 -
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/SchemaBase.java | 4
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/parser/FormDefault.java | 10
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/parser/SchemaParser.java | 20
ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/parser/XmlNamespace.java | 1
35 files changed, 1845 insertions(+), 1090 deletions(-)
New commits:
commit d02054a68cb37e3b3d3485116ef835e875928763
Author: Andre Fischer <af at apache.org>
Date: Thu Jun 12 07:15:24 2014 +0000
125035: Added support for attributes.
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AcceptingStateTable.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AcceptingStateTable.java
index 006c187..151cf8a 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AcceptingStateTable.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AcceptingStateTable.java
@@ -23,7 +23,6 @@ public class AcceptingStateTable
maAcceptingStates.add(nStateId);
}
- Log.Std.printf("read %d accepting states\n", maAcceptingStates.size());
}
@@ -37,5 +36,13 @@ public class AcceptingStateTable
+ public int GetAcceptingStateCount ()
+ {
+ return maAcceptingStates.size();
+ }
+
+
+
+
private final Set<Integer> maAcceptingStates;
}
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeDescriptor.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeDescriptor.java
new file mode 100644
index 0000000..a79832a
--- /dev/null
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeDescriptor.java
@@ -0,0 +1,112 @@
+package org.apache.openoffice.ooxml.parser;
+
+/** Store information about a single attribute (per state) that was read
+ * from the parse table.
+ *
+ * Note that an attribute that is defined for more than one state has one
+ * AttributeDescriptor object per state.
+ *
+ */
+public class AttributeDescriptor
+{
+ public AttributeDescriptor (
+ final int nPrefixId,
+ final int nAttributeId,
+ final boolean bCanBeUnqualified,
+ final boolean bIsOptional,
+ final String sDefaultValue,
+ final String sAttributeName,
+ final String sAttributeType)
+ {
+ mnNamespaceId = nPrefixId;
+ mnAttributeId = nAttributeId;
+ mbCanBeUnqualified = bCanBeUnqualified;
+ mbIsOptional = bIsOptional;
+ msDefaultValue = sDefaultValue;
+ msAttributeName = sAttributeName;
+ msAttributeType = sAttributeType;
+ }
+
+
+
+
+ public String GetType()
+ {
+ if (msAttributeType != null)
+ return msAttributeType;
+ else
+ return "<undefined>";
+ }
+
+
+
+
+ public int GetNamespaceId ()
+ {
+ return mnNamespaceId;
+ }
+
+
+
+
+ public int GetNameId ()
+ {
+ return mnAttributeId;
+ }
+
+
+
+
+ public boolean CanBeUnqualified ()
+ {
+ return mbCanBeUnqualified;
+ }
+
+
+
+
+ public boolean IsOptional ()
+ {
+ return mbIsOptional;
+ }
+
+
+
+
+ public String GetDefaultValue ()
+ {
+ return msDefaultValue;
+ }
+
+
+
+
+ public String GetName ()
+ {
+ return msAttributeName;
+ }
+
+
+
+
+ @Override
+ public String toString ()
+ {
+ return String.format(
+ "attribute %s(%d) of type %s",
+ msAttributeName,
+ mnAttributeId,
+ msAttributeType);
+ }
+
+
+
+
+ private final int mnNamespaceId;
+ private final int mnAttributeId;
+ private final boolean mbCanBeUnqualified;
+ private final boolean mbIsOptional;
+ private final String msDefaultValue;
+ private final String msAttributeName;
+ private final String msAttributeType;
+}
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeManager.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeManager.java
index 5c65bdb..c8034d4 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeManager.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeManager.java
@@ -22,57 +22,193 @@
package org.apache.openoffice.ooxml.parser;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
-import java.util.Map.Entry;
+import java.util.Set;
import java.util.Vector;
+
+/** Match a set of attributes from the document with the attribute
+ * specifications of a state.
+ *
+ */
public class AttributeManager
{
- public AttributeManager (final Vector<String[]> aData)
+ /** Create a new AttributeManager for the attribute specifications that
+ * are given in the parse table.
+ */
+ public AttributeManager (
+ final Vector<String[]> aData,
+ final NamespaceMap aNamespaceMap,
+ final NameMap aNameMap)
{
maStateIdToAttributesMap = new HashMap<>();
+ maNamespaceMap = aNamespaceMap;
+ maNameMap = aNameMap;
+
+ for (final String[] aLine : aData)
+ {
+ final int nStateId = Integer.parseInt(aLine[1]);
+ final int nPrefixId = Integer.parseInt(aLine[2]);
+ final boolean bCanBeUnqualified = aLine[3].startsWith("u");
+ final int nAttributeId = Integer.parseInt(aLine[4]);
+ final String sAttributeType = aLine[5];
+ final boolean bIsOptional = aLine[6].startsWith("o");
+ final String sDefault = UnquoteString(aLine[7]);
+ final String sAttributeName = aLine[8];
+
+ Map<Integer,AttributeDescriptor> aAttributesPerState = maStateIdToAttributesMap.get(nStateId);
+ if (aAttributesPerState == null)
+ {
+ aAttributesPerState = new HashMap<>();
+ maStateIdToAttributesMap.put(nStateId, aAttributesPerState);
+ }
+
+ final AttributeDescriptor aAttributeDescriptor = new AttributeDescriptor(
+ nPrefixId,
+ nAttributeId,
+ bCanBeUnqualified,
+ bIsOptional,
+ sDefault,
+ sAttributeName,
+ sAttributeType);
+
+ aAttributesPerState.put(
+ (nPrefixId<<16)|nAttributeId,
+ aAttributeDescriptor);
+ if (bCanBeUnqualified)
+ aAttributesPerState.put(
+ nAttributeId,
+ aAttributeDescriptor);
+ }
}
+ /** For the state with id nStateId, match the attributes from the document
+ * with the attribute specifications of that state.
+ */
public void ParseAttributes (
final int nStateId,
- final AttributeProvider aAttributeProvider)
+ final AttributeProvider aDocumentAttributes)
{
- final Map<String,String> aAttributeDefinitions = maStateIdToAttributesMap.get(nStateId);
- if (aAttributeDefinitions == null)
+ final Map<Integer,AttributeDescriptor> aAttributesPerState = maStateIdToAttributesMap.get(nStateId);
+ if (aAttributesPerState == null)
{
- // if (aAttributeProvider.HasAttributes())
- //throw new RuntimeException();
+ if (aDocumentAttributes.HasAttributes())
+ {
+ Log.Std.printf("state has not attributes defined but document provides %d attributes\n",
+ aDocumentAttributes.GetAttributeCount());
+ for (final String[] aEntry : aDocumentAttributes)
+ {
+ Log.Dbg.printf(" %s -> %s\n", aEntry[0], aEntry[1]);
+ }
+ throw new RuntimeException();
+ }
}
else
{
- for (final Entry<String,String> aEntry : aAttributeProvider)
+ final Set<AttributeDescriptor> aUsedAttributes = new HashSet<>();
+
+ // Process all attributes from the document.
+ for (final String[] aEntry : aDocumentAttributes)
{
- ParseAttributeValue(
- aEntry.getKey(),
- aEntry.getValue(),
- aAttributeDefinitions.get(aEntry.getKey()));
+ final AttributeDescriptor aAttributeDescriptor = ProcessAttribute(
+ aEntry[0],
+ aEntry[1],
+ aEntry[2],
+ aAttributesPerState);
+ aUsedAttributes.add(aAttributeDescriptor);
+ if (Log.Dbg != null)
+ {
+ if (aAttributeDescriptor == null)
+ Log.Dbg.printf("attribute %s%s is not known\n",
+ aEntry[0]==null ? "" : ":"+aEntry[0],
+ aEntry[1]);
+ else
+ Log.Dbg.printf("attribute %s:%s(%d:%d) has type and value %s\n",
+ maNamespaceMap.GetDescriptorForId(aAttributeDescriptor.GetNamespaceId()).Prefix,
+ maNameMap.GetNameForId(aAttributeDescriptor.GetNameId()),
+ aAttributeDescriptor.GetNamespaceId(),
+ aAttributeDescriptor.GetNameId(),
+ aAttributeDescriptor.GetType(),
+ aEntry[2]);
+ }
}
+
+ // Check if all required attributes where given.
+ for (final AttributeDescriptor aAttribute : aAttributesPerState.values())
+ {
+ if ( ! aAttribute.IsOptional())
+ {
+ if ( ! aUsedAttributes.contains(aAttribute))
+ throw new RuntimeException("attribute '"+aAttribute.GetName()+"' is not present but also not optional");
+ }
+ }
+ }
+ }
+
+
+
+
+ private AttributeDescriptor ProcessAttribute (
+ final String sNamespace,
+ final String sAttributeName,
+ final String sAttributeValue,
+ final Map<Integer,AttributeDescriptor> aAttributesPerState)
+ {
+ final AttributeDescriptor aAttributeDescriptor;
+ if (sNamespace == null)
+ {
+ // Attribute name has no namespace.
+ final int nAttributeNameId = maNameMap.GetIdForName(sAttributeName);
+ aAttributeDescriptor = aAttributesPerState.get(nAttributeNameId);
+ }
+ else
+ {
+ // Attribute name has explicit namespace.
+ final NamespaceMap.NamespaceDescriptor aDescriptor = maNamespaceMap.GetDescriptorForURI(sNamespace);
+ final int nAttributeNameId = maNameMap.GetIdForName(sAttributeName);
+ aAttributeDescriptor = aAttributesPerState.get((aDescriptor.Id<<16) | nAttributeNameId);
+ }
+ return aAttributeDescriptor;
+ }
+
+
+
+
+ /** Remove the quotes around the given string.
+ * If it has the special value null (without quotes) then the null reference
+ * is returned.
+ */
+ private String UnquoteString (final String sValue)
+ {
+ if (sValue.equals("null"))
+ return null;
+ else
+ {
+ assert(sValue.startsWith("\""));
+ assert(sValue.endsWith("\""));
+ return sValue.substring(1, sValue.length()-1);
}
}
- private void ParseAttributeValue (
- final String sName,
- final String sValue,
- final String sSimpleTypeName)
+
+ public int GetAttributeCount ()
{
- Log.Dbg.printf("attribute %s has type %s and value %s\n",
- sName,
- sSimpleTypeName,
- sValue);
+ int nCount = 0;
+ for (final Map<Integer,AttributeDescriptor> aMap : maStateIdToAttributesMap.values())
+ nCount += aMap.size();
+ return nCount;
}
- private final Map<String,Map<String,String>> maStateIdToAttributesMap;
+ private final Map<Integer,Map<Integer,AttributeDescriptor>> maStateIdToAttributesMap;
+ private final NamespaceMap maNamespaceMap;
+ private final NameMap maNameMap;
}
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeProvider.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeProvider.java
index bf9d24c..fda82f4 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeProvider.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/AttributeProvider.java
@@ -22,12 +22,13 @@
package org.apache.openoffice.ooxml.parser;
import java.util.Iterator;
-import java.util.Map.Entry;
import javax.xml.stream.XMLStreamReader;
+/** Give access to the attributes that are read from an OOXML stream.
+ */
public class AttributeProvider
- implements Iterable<Entry<String,String>>
+ implements Iterable<String[]>
{
public AttributeProvider(XMLStreamReader aReader)
{
@@ -52,9 +53,9 @@ public class AttributeProvider
@Override
- public Iterator<Entry<String,String>> iterator ()
+ public Iterator<String[]> iterator ()
{
- return new Iterator<Entry<String,String>> ()
+ return new Iterator<String[]> ()
{
int nIndex = 0;
final int nCount = maReader.getAttributeCount();
@@ -64,30 +65,16 @@ public class AttributeProvider
return nIndex < nCount;
}
- @Override public Entry<String, String> next()
+ @Override public String[] next()
{
- final Entry<String,String> aEntry = new Entry<String,String>()
- {
- final String msKey = maReader.getAttributeLocalName(nIndex);
- final String msValue = maReader.getAttributeValue(nIndex);
-
- @Override public String getKey()
- {
- return msKey;
- }
-
- @Override public String getValue()
+ final String[] aResult = new String[]
{
- return msValue;
- }
-
- @Override public String setValue (final String sValue)
- {
- return null;
- }
- };
+ maReader.getAttributeNamespace(nIndex),
+ maReader.getAttributeLocalName(nIndex),
+ maReader.getAttributeValue(nIndex)
+ };
++nIndex;
- return aEntry;
+ return aResult;
}
@Override public void remove()
@@ -97,5 +84,16 @@ public class AttributeProvider
};
}
+
+
+
+ public Integer GetAttributeCount ()
+ {
+ return maReader.getAttributeCount();
+ }
+
+
+
+
private final XMLStreamReader maReader;
}
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NameMap.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NameMap.java
index 0fffe78..fe4424d 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NameMap.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NameMap.java
@@ -42,24 +42,14 @@ public class NameMap
maIdToNameMap.setSize(nId+1);
maIdToNameMap.set(nId, aLine[2]);
}
-
- if (Log.Dbg != null)
- Log.Dbg.printf("initialized name map with %d definitions\n", maNameToIdMap.size());
}
public int GetIdForName (
- final String sPrefix,
- final String sElementName)
+ final String sName)
{
- final String sName;
- if (sPrefix == null)
- sName = sElementName;
- else
- sName = sPrefix+"_"+sElementName;
-
if ( ! maNameToIdMap.containsKey(sName))
throw new RuntimeException("token '"+sName+"' is not known");
@@ -80,6 +70,14 @@ public class NameMap
+ public int GetNameCount ()
+ {
+ return maIdToNameMap.size();
+ }
+
+
+
+
private final Map<String,Integer> maNameToIdMap;
private final Vector<String> maIdToNameMap;
}
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NamespaceMap.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NamespaceMap.java
index 214a008..e12f1b5 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NamespaceMap.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/NamespaceMap.java
@@ -27,31 +27,65 @@ import java.util.Vector;
public class NamespaceMap
{
+ class NamespaceDescriptor
+ {
+ NamespaceDescriptor (final String sPrefix, final int nId)
+ {
+ Prefix = sPrefix;
+ Id = nId;
+ }
+ public final String Prefix;
+ public final int Id;
+ }
NamespaceMap (final Vector<String[]> aData)
{
- maUriToPrefixMap = new HashMap<>();
+ maUriToDescriptorMap = new HashMap<>();
+ maIdToDescriptorMap = new HashMap<>();
for (final String[] aLine : aData)
{
- maUriToPrefixMap.put(aLine[2], aLine[1]);
+ final int nId = Integer.parseInt(aLine[2]);
+ final NamespaceDescriptor aDescriptor = new NamespaceDescriptor(aLine[1], nId);
+ maUriToDescriptorMap.put(
+ aLine[3],
+ aDescriptor);
+ maIdToDescriptorMap.put(
+ nId,
+ aDescriptor);
}
-
- if (Log.Dbg != null)
- Log.Dbg.printf("initialized namespace map with %d definitions\n", maUriToPrefixMap.size());
}
- public String GetPrefixForURI (final String sURI)
+ public NamespaceDescriptor GetDescriptorForURI (final String sURI)
{
- if ( ! maUriToPrefixMap.containsKey(sURI))
+ if (sURI == null)
+ throw new RuntimeException("namespace is null");
+ if ( ! maUriToDescriptorMap.containsKey(sURI))
throw new RuntimeException("namespace '"+sURI+"' is not known");
- return maUriToPrefixMap.get(sURI);
+ return maUriToDescriptorMap.get(sURI);
+ }
+
+
+
+
+ public NamespaceDescriptor GetDescriptorForId (final int nId)
+ {
+ return maIdToDescriptorMap.get(nId);
+ }
+
+
+
+
+ public int GetNamespaceCount ()
+ {
+ return maUriToDescriptorMap.size();
}
- private final Map<String,String> maUriToPrefixMap;
+ private final Map<String,NamespaceDescriptor> maUriToDescriptorMap;
+ private final Map<Integer,NamespaceDescriptor> maIdToDescriptorMap;
}
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/OOXMLParser.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/OOXMLParser.java
index 64abf25..398ff58 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/OOXMLParser.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/OOXMLParser.java
@@ -48,8 +48,20 @@ public class OOXMLParser
*/
public static void main (final String ... aArgumentList)
{
- if (aArgumentList.length != 3)
- throw new RuntimeException("usage: OOXMLParser <parser-tables-path> <XML-input-file> <log-file>");
+ if (aArgumentList.length<2 ||aArgumentList.length>3)
+ throw new RuntimeException("usage: OOXMLParser <parser-tables-path> <XML-input-file> <log-file>?");
+
+ if (aArgumentList.length == 3)
+ {
+ final File aLogFile = new File(aArgumentList[2]);
+ Log.Dbg = new Log(aLogFile);
+ System.out.printf("writing log data to %s\n", aLogFile.toString());
+ }
+ else
+ {
+ Log.Dbg = null;
+ System.out.printf("writing no log data\n");
+ }
long nStartTime = System.currentTimeMillis();
final StateMachine aMachine = new StateMachine(new File(aArgumentList[0]));
@@ -63,7 +75,7 @@ public class OOXMLParser
if (aReader != null)
{
nStartTime = System.currentTimeMillis();
- final int nElementCount = Parse(aReader, aMachine, new File(aArgumentList[2]));
+ final int nElementCount = Parse(aReader, aMachine);
nEndTime = System.currentTimeMillis();
System.out.printf("parsed %d elements in %fs\n",
nElementCount,
@@ -77,6 +89,8 @@ public class OOXMLParser
}
+
+
private static InputStream GetInputStream (final String sInputName)
{
final InputStream aIn;
@@ -146,11 +160,8 @@ public class OOXMLParser
private static int Parse (
final XMLStreamReader aReader,
- final StateMachine aMachine,
- final File aLogFile)
+ final StateMachine aMachine)
{
- Log.Dbg = new Log(aLogFile);
-
int nElementCount = 0;
try
{
@@ -164,7 +175,8 @@ public class OOXMLParser
++nElementCount;
if (aMachine.IsInSkipState())
{
- Log.Dbg.printf("is skip state -> starting to skip\n");
+ if (Log.Dbg != null)
+ Log.Dbg.printf("is skip state -> starting to skip\n");
nElementCount += Skip(aReader);
}
else if ( ! aMachine.ProcessStartElement(
@@ -173,7 +185,8 @@ public class OOXMLParser
aReader.getLocation(),
aAttributeProvider))
{
- Log.Dbg.printf("starting to skip to recover from error\n");
+ if (Log.Dbg != null)
+ Log.Dbg.printf("starting to skip to recover from error\n");
nElementCount += Skip(aReader);
}
break;
@@ -187,7 +200,8 @@ public class OOXMLParser
case XMLStreamReader.CHARACTERS:
final String sText = aReader.getText();
- Log.Dbg.printf("text [%s]\n", sText.replace("\n", "\\n"));
+ if (Log.Dbg != null)
+ Log.Dbg.printf("text [%s]\n", sText.replace("\n", "\\n"));
aMachine.ProcessCharacters(sText);
break;
@@ -215,11 +229,14 @@ public class OOXMLParser
private static int Skip (final XMLStreamReader aReader)
{
- Log.Dbg.printf("starting to skip on %s at L%dC%d\n",
- aReader.getLocalName(),
- aReader.getLocation().getLineNumber(),
- aReader.getLocation().getColumnNumber());
- Log.Dbg.IncreaseIndentation();
+ if (Log.Dbg != null)
+ {
+ Log.Dbg.printf("starting to skip on %s at L%dC%d\n",
+ aReader.getLocalName(),
+ aReader.getLocation().getLineNumber(),
+ aReader.getLocation().getColumnNumber());
+ Log.Dbg.IncreaseIndentation();
+ }
// We are called when processing a start element. This means that we are
// already at relative depth 1.
@@ -235,16 +252,21 @@ public class OOXMLParser
case XMLStreamReader.START_ELEMENT:
++nRelativeDepth;
++nElementCount;
- Log.Dbg.printf("skipping start element %s\n", aReader.getLocalName());
- Log.Dbg.IncreaseIndentation();
+ if (Log.Dbg != null)
+ {
+ Log.Dbg.printf("skipping start element %s\n", aReader.getLocalName());
+ Log.Dbg.IncreaseIndentation();
+ }
break;
case XMLStreamReader.END_ELEMENT:
--nRelativeDepth;
- Log.Dbg.DecreaseIndentation();
+ if (Log.Dbg != null)
+ Log.Dbg.DecreaseIndentation();
if (nRelativeDepth <= 0)
{
- Log.Dbg.printf("leaving skip mode on %s\n", aReader.getLocalName());
+ if (Log.Dbg != null)
+ Log.Dbg.printf("leaving skip mode on %s\n", aReader.getLocalName());
return nElementCount;
}
break;
@@ -257,7 +279,9 @@ public class OOXMLParser
break;
default:
- Log.Dbg.printf("%s\n", nCode);
+ if (Log.Dbg != null)
+ Log.Dbg.printf("%s\n", nCode);
+ break;
}
}
}
@@ -270,8 +294,10 @@ public class OOXMLParser
+
private static void SkipText (final String sText)
{
- Log.Dbg.printf("skipping text [%s]\n", sText.replace("\n", "\\n"));
+ if (Log.Dbg != null)
+ Log.Dbg.printf("skipping text [%s]\n", sText.replace("\n", "\\n"));
}
}
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/ParseTableReader.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/ParseTableReader.java
index b38a2c8..d8426cb 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/ParseTableReader.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/ParseTableReader.java
@@ -30,6 +30,11 @@ public class ParseTableReader
break;
if (sLine.startsWith("#"))
continue;
+
+ // Splitting just at whitespace may be too simple to keep quoted text
+ // (used e.g. for attribute default values) in one peace when
+ // it contains whitespace. Should this case occur than this
+ // implementation has to be improved.
final String aParts[] = sLine.split("\\s+");
GetSection(aParts[0]).add(aParts);
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/SkipStateTable.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/SkipStateTable.java
index bc0c76b..a609aa7 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/SkipStateTable.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/SkipStateTable.java
@@ -24,7 +24,6 @@ public class SkipStateTable
maSkipStates.add(nStateId);
}
- Log.Std.printf("read %d skip states\n", maSkipStates.size());
}
@@ -38,5 +37,13 @@ public class SkipStateTable
+ public int GetSkipStateCount ()
+ {
+ return maSkipStates.size();
+ }
+
+
+
+
private final Set<Integer> maSkipStates;
}
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/StateMachine.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/StateMachine.java
index 72a2a33..6b19977 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/StateMachine.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/StateMachine.java
@@ -33,20 +33,37 @@ public class StateMachine
{
public StateMachine (final File aParseTableFile)
{
+ if (Log.Dbg != null)
+ Log.Dbg.printf("reading parse tables from %s\n", aParseTableFile.toString());
+
final ParseTableReader aReader = new ParseTableReader(aParseTableFile);
maNamespaceMap = new NamespaceMap(aReader.GetSection("namespace"));
- maElementNameMap = new NameMap(aReader.GetSection("element-name"));
+ maNameMap = new NameMap(aReader.GetSection("name"));
maStateNameMap = new NameMap(aReader.GetSection("state-name"));
maTransitions = new TransitionTable(aReader.GetSection("transition"));
maSkipStates = new SkipStateTable(aReader.GetSection("skip"));
maAcceptingStates = new AcceptingStateTable(aReader.GetSection("accepting-state"));
- maAttributeManager = new AttributeManager(aReader.GetSection("attribute"));
+ maAttributeManager = new AttributeManager(
+ aReader.GetSection("attribute"),
+ maNamespaceMap,
+ maNameMap);
+
+ System.out.printf("read %d namespace, %d names, %d states (%d skip, %d accept), %d transitions and %d attributes\n",
+ maNamespaceMap.GetNamespaceCount(),
+ maNameMap.GetNameCount(),
+ maStateNameMap.GetNameCount(),
+ maSkipStates.GetSkipStateCount(),
+ maAcceptingStates.GetAcceptingStateCount(),
+ maTransitions.GetTransitionCount(),
+ maAttributeManager.GetAttributeCount());
mnStartStateId = Integer.parseInt(aReader.GetSection("start-state").firstElement()[1]);
mnEndStateId = Integer.parseInt(aReader.GetSection("end-state").firstElement()[1]);
mnCurrentStateId = mnStartStateId;
maStateStack = new Stack<>();
- Log.Dbg.printf("starting in state _start_ (%d)\n", mnCurrentStateId);
+
+ if (Log.Dbg != null)
+ Log.Dbg.printf("starting in state _start_ (%d)\n", mnCurrentStateId);
}
@@ -62,41 +79,49 @@ public class StateMachine
try
{
- final String sPrefix = maNamespaceMap.GetPrefixForURI(sNamespaceURI);
- final int nElementId = maElementNameMap.GetIdForName(sPrefix, sElementName);
- Log.Dbg.printf("%s:%s(%d) L%dC%d\n",
- sPrefix,
- sElementName,
- nElementId,
- aLocation.getLineNumber(),
- aLocation.getColumnNumber());
+ final NamespaceMap.NamespaceDescriptor aDescriptor = maNamespaceMap.GetDescriptorForURI(sNamespaceURI);
+ final int nElementNameId = maNameMap.GetIdForName(sElementName);
+ if (Log.Dbg != null)
+ Log.Dbg.printf("%s:%s(%d:%d) L%dC%d\n",
+ aDescriptor.Prefix,
+ sElementName,
+ aDescriptor.Id,
+ nElementNameId,
+ aLocation.getLineNumber(),
+ aLocation.getColumnNumber());
final Transition aTransition = maTransitions.GetTransition(
mnCurrentStateId,
- nElementId);
+ aDescriptor.Id,
+ nElementNameId);
if (aTransition == null)
{
final String sText = String.format(
- "can not find transition for state %s(%d) and element %s(%d) at L%dC%d\n",
+ "can not find transition for state %s(%d) and element %s(%d:%d) at L%dC%d\n",
maStateNameMap.GetNameForId(mnCurrentStateId),
mnCurrentStateId,
- maElementNameMap.GetNameForId(nElementId),
- nElementId,
+ aDescriptor.Id,
+ maNameMap.GetNameForId(nElementNameId),
+ nElementNameId,
aLocation.getLineNumber(),
aLocation.getColumnNumber());
Log.Err.printf(sText);
- Log.Dbg.printf(sText);
+ if (Log.Dbg != null)
+ Log.Dbg.printf(sText);
}
else
{
- Log.Dbg.printf(" %s(%d) -> %s(%d) via %s(%d)",
- maStateNameMap.GetNameForId(mnCurrentStateId),
- mnCurrentStateId,
- maStateNameMap.GetNameForId(aTransition.GetEndStateId()),
- aTransition.GetEndStateId(),
- maStateNameMap.GetNameForId(aTransition.GetActionId()),
- aTransition.GetActionId());
- Log.Dbg.printf("\n");
+ if (Log.Dbg != null)
+ {
+ Log.Dbg.printf(" %s(%d) -> %s(%d) via %s(%d)",
+ maStateNameMap.GetNameForId(mnCurrentStateId),
+ mnCurrentStateId,
+ maStateNameMap.GetNameForId(aTransition.GetEndStateId()),
+ aTransition.GetEndStateId(),
+ maStateNameMap.GetNameForId(aTransition.GetActionId()),
+ aTransition.GetActionId());
+ Log.Dbg.printf("\n");
+ }
final int nOldState = mnCurrentStateId;
SetCurrentState(aTransition.GetEndStateId());
@@ -108,7 +133,7 @@ public class StateMachine
}
catch (RuntimeException aException)
{
- System.err.printf("error at line %d and column %d\n",
+ Log.Err.printf("error at line %d and column %d\n",
aLocation.getLineNumber(),
aLocation.getColumnNumber());
throw aException;
@@ -127,28 +152,32 @@ public class StateMachine
if ( ! maAcceptingStates.Contains(mnCurrentStateId)
&& mnCurrentStateId!=-1)
{
- Log.Dbg.printf("current state %s(%d) is not an accepting state\n",
- maStateNameMap.GetNameForId(mnCurrentStateId),
- mnCurrentStateId);
+ if (Log.Dbg != null)
+ Log.Dbg.printf("current state %s(%d) is not an accepting state\n",
+ maStateNameMap.GetNameForId(mnCurrentStateId),
+ mnCurrentStateId);
throw new RuntimeException("not expecting end element "+sElementName);
}
- final String sPrefix = maNamespaceMap.GetPrefixForURI(sNamespaceURI);
+ final NamespaceMap.NamespaceDescriptor aDescriptor = maNamespaceMap.GetDescriptorForURI(sNamespaceURI);
final int nOldStateId = mnCurrentStateId;
SetCurrentState(maStateStack.pop());
- Log.Dbg.DecreaseIndentation();
- Log.Dbg.printf("/%s:%s L%d%d\n",
- sPrefix,
- sElementName,
- aLocation.getLineNumber(),
- aLocation.getColumnNumber());
- Log.Dbg.printf(" %s(%d) <- %s(%d)\n",
- maStateNameMap.GetNameForId(nOldStateId),
- nOldStateId,
- maStateNameMap.GetNameForId(mnCurrentStateId),
- mnCurrentStateId);
+ if (Log.Dbg != null)
+ {
+ Log.Dbg.DecreaseIndentation();
+ Log.Dbg.printf("/%s:%s L%d%d\n",
+ aDescriptor.Prefix,
+ sElementName,
+ aLocation.getLineNumber(),
+ aLocation.getColumnNumber());
+ Log.Dbg.printf(" %s(%d) <- %s(%d)\n",
+ maStateNameMap.GetNameForId(nOldStateId),
+ nOldStateId,
+ maStateNameMap.GetNameForId(mnCurrentStateId),
+ mnCurrentStateId);
+ }
}
@@ -191,17 +220,20 @@ public class StateMachine
final int nNewState)
{
maStateStack.push(mnCurrentStateId);
- Log.Dbg.IncreaseIndentation();
+ if (Log.Dbg != null)
+ Log.Dbg.IncreaseIndentation();
final int nActionId = aTransition.GetActionId();
SetCurrentState(nActionId);
- maAttributeManager.ParseAttributes(nActionId, aAttributes);
+ maAttributeManager.ParseAttributes(
+ nActionId,
+ aAttributes);
}
private final NamespaceMap maNamespaceMap;
- private final NameMap maElementNameMap;
+ private final NameMap maNameMap;
private final NameMap maStateNameMap;
private final TransitionTable maTransitions;
private final AttributeManager maAttributeManager;
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/TransitionTable.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/TransitionTable.java
index 3f0bb65..32326da 100644
--- a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/TransitionTable.java
+++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/TransitionTable.java
@@ -30,21 +30,20 @@ public class TransitionTable
public TransitionTable (final Vector<String[]> aData)
{
maTransitions = new HashMap<>();
- int nTransitionCount = 0;
for (final String[] aLine : aData)
{
// Create new transition.
final int nStartStateId = Integer.parseInt(aLine[1]);
final int nEndStateId = Integer.parseInt(aLine[2]);
- final int nElementId = Integer.parseInt(aLine[3]);
- final int nElementStateId = Integer.parseInt(aLine[4]);
+ final int nElementPrefixId = Integer.parseInt(aLine[3]);
+ final int nElementLocalId = Integer.parseInt(aLine[4]);
+ final int nElementStateId = Integer.parseInt(aLine[5]);
final Transition aTransition = new Transition(
nStartStateId,
nEndStateId,
- nElementId,
+ (nElementPrefixId<<16) | nElementLocalId,
nElementStateId);
- ++nTransitionCount;
Map<Integer,Transition> aPerElementTransitions = maTransitions.get(aTransition.GetStartStateId());
if (aPerElementTransitions == null)
@@ -54,7 +53,6 @@ public class TransitionTable
}
aPerElementTransitions.put(aTransition.GetElementId(), aTransition);
}
- Log.Std.printf("read %d transitions\n", nTransitionCount);
}
@@ -62,13 +60,22 @@ public class TransitionTable
public Transition GetTransition (
final int nStateId,
- final int nElementId)
+ final int nPrefixId,
+ final int nLocalId)
{
Map<Integer,Transition> aPerElementTransitions = maTransitions.get(nStateId);
if (aPerElementTransitions == null)
return null;
else
- return aPerElementTransitions.get(nElementId);
+ return aPerElementTransitions.get((nPrefixId<<16) | nLocalId);
+ }
+
+
+
+
+ public int GetTransitionCount ()
+ {
+ return maTransitions.size();
}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/SchemaReader.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/SchemaReader.java
index c770a34..a1f5d3f 100644
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/SchemaReader.java
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/SchemaReader.java
@@ -37,10 +37,10 @@ import javax.xml.stream.XMLStreamException;
import org.apache.openoffice.ooxml.schema.automaton.FiniteAutomatonContainer;
import org.apache.openoffice.ooxml.schema.automaton.NonValidatingCreator;
-import org.apache.openoffice.ooxml.schema.automaton.FiniteAutomaton;
import org.apache.openoffice.ooxml.schema.automaton.ValidatingCreator;
import org.apache.openoffice.ooxml.schema.generator.LogGenerator;
import org.apache.openoffice.ooxml.schema.generator.ParserTablesGenerator;
+import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
import org.apache.openoffice.ooxml.schema.model.schema.Schema;
import org.apache.openoffice.ooxml.schema.model.schema.SchemaBase;
import org.apache.openoffice.ooxml.schema.parser.SchemaParser;
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/Test.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/Test.java
index dff3508..ea2565f 100644
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/Test.java
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/Test.java
@@ -53,6 +53,7 @@ public class Test
HopcroftMinimizer.MinimizeDFA (
new StateContainer(),
aStates,
+ null,
System.out);
}
}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/CreatorBase.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/CreatorBase.java
new file mode 100644
index 0000000..239dba196
--- /dev/null
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/CreatorBase.java
@@ -0,0 +1,124 @@
+package org.apache.openoffice.ooxml.schema.automaton;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import org.apache.openoffice.ooxml.schema.iterator.AttributeIterator;
+import org.apache.openoffice.ooxml.schema.iterator.DereferencingNodeIterator;
+import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
+import org.apache.openoffice.ooxml.schema.model.base.INode;
+import org.apache.openoffice.ooxml.schema.model.schema.SchemaBase;
+
+/** Base class of the creator classes for DFAs and NFAs.
+ */
+public class CreatorBase
+{
+ CreatorBase (
+ final SchemaBase aSchemaBase,
+ final File aLogFile)
+ {
+ maSchemaBase = aSchemaBase;
+ maStateContainer = new StateContainer();
+
+ PrintStream aLog = null;
+ try
+ {
+ aLog = new PrintStream(new FileOutputStream(aLogFile));
+ }
+ catch (FileNotFoundException e)
+ {
+ e.printStackTrace();
+ }
+ maLog = aLog;
+ msLogIndentation = "";
+ }
+
+
+
+
+ protected Vector<Attribute> CollectAttributes (final INode aRoot)
+ {
+ final Vector<Attribute> aAttributes = new Vector<>();
+ for (final INode aNode : new DereferencingNodeIterator(aRoot, maSchemaBase, true))
+ for (final Attribute aAttribute : new AttributeIterator(aNode, maSchemaBase))
+ aAttributes.add(aAttribute);
+ return aAttributes;
+ }
+
+
+
+
+ protected void AddSkipTransition (
+ final State aState,
+ final SkipData aSkipData)
+ {
+ aState.AddSkipData(aSkipData);
+
+ if (maLog != null)
+ {
+ maLog.printf("%sskip state %s\n",
+ msLogIndentation,
+ aState.GetFullname());
+ }
+ }
+
+
+
+
+ protected void ProcessAttributes (final INode aNode)
+ {
+ for (final Attribute aAttribute : new AttributeIterator(aNode, maSchemaBase))
+ {
+ maLog.printf("%sattribute %s\n",
+ msLogIndentation,
+ aAttribute.GetName().GetDisplayName());
+ maAttributes.add(aAttribute);
+ }
+ }
+
+
+
+
+ protected void AddComment (
+ final String sFormat,
+ final Object ... aArgumentList)
+ {
+ if (maLog != null)
+ {
+ maLog.print(msLogIndentation);
+ maLog.print("// ");
+ maLog.printf(sFormat, aArgumentList);
+ maLog.print("\n");
+ }
+ }
+
+
+
+
+ protected void StartBlock ()
+ {
+ if (maLog != null)
+ msLogIndentation += " ";
+ }
+
+
+
+
+ protected void EndBlock ()
+ {
+ if (maLog != null)
+ msLogIndentation = msLogIndentation.substring(4);
+ }
+
+
+
+
+ protected final SchemaBase maSchemaBase;
+ protected final StateContainer maStateContainer;
+ protected final PrintStream maLog;
+ protected String msLogIndentation;
+ protected Vector<Attribute> maAttributes;
+}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/DFACreator.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/DFACreator.java
index a0ba1c3..64b2bcc 100644
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/DFACreator.java
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/DFACreator.java
@@ -12,6 +12,7 @@ import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
+import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
/** Convert an NFA into a DFA via the powerset construction (also called subset
@@ -25,11 +26,14 @@ public class DFACreator
public static FiniteAutomaton CreateDFAforNFA (
final StateContainer aDFAStateContainer,
final StateContext aNFAStateContext,
+ final Vector<Attribute> aAttributes,
final QualifiedName aTypeName)
{
final DFACreator aCreator = new DFACreator(aDFAStateContainer, aNFAStateContext, aTypeName);
aCreator.CreateDFAforNFA();
- return new FiniteAutomaton(aCreator.maDFAStateContext);
+ return new FiniteAutomaton(
+ aCreator.maDFAStateContext,
+ aAttributes);
}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomaton.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomaton.java
index 999824c..8c4cf6e 100644
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomaton.java
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomaton.java
@@ -23,6 +23,7 @@ package org.apache.openoffice.ooxml.schema.automaton;
import java.util.Vector;
+import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
@@ -37,9 +38,13 @@ import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
public class FiniteAutomaton
{
FiniteAutomaton (
- final StateContext aContext)
+ final StateContext aContext,
+ final Vector<Attribute> aAttributes)
{
maStateContext = aContext;
+ maAttributes = aAttributes!=null
+ ? aAttributes
+ : new Vector<Attribute>();
}
@@ -92,6 +97,7 @@ public class FiniteAutomaton
return DFACreator.CreateDFAforNFA(
aDFAContainer,
maStateContext,
+ maAttributes,
aTypeName);
}
@@ -137,5 +143,14 @@ public class FiniteAutomaton
+ public Vector<Attribute> GetAttributes ()
+ {
+ return maAttributes;
+ }
+
+
+
+
private final StateContext maStateContext;
+ private final Vector<Attribute> maAttributes;
}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomatonContainer.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomatonContainer.java
index 5ac2e66..fbd8407 100644
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomatonContainer.java
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/FiniteAutomatonContainer.java
@@ -72,18 +72,6 @@ public class FiniteAutomatonContainer
- public Iterable<Transition> GetTransitions ()
- {
- final Vector<Transition> aTransitions = new Vector<>();
- for (final FiniteAutomaton aAutomaton : maComplexTypeNameToAutomatonMap.values())
- for (final Transition aTransition : aAutomaton.GetTransitions())
- aTransitions.add(aTransition);
- return aTransitions;
- }
-
-
-
-
public int GetTransitionCount ()
{
int nTransitionCount = 0;
@@ -135,6 +123,7 @@ public class FiniteAutomatonContainer
HopcroftMinimizer.MinimizeDFA(
aNewStateContainer,
aEntry.getValue().GetStateContext(),
+ aEntry.getValue().GetAttributes(),
aLog));
}
return aDFAs;
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/HopcroftMinimizer.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/HopcroftMinimizer.java
index 6d50592..195af7a 100644
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/HopcroftMinimizer.java
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/HopcroftMinimizer.java
@@ -9,7 +9,9 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.Vector;
+import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
/** Minimize an DFA with respect to its number of states.
@@ -24,6 +26,7 @@ public class HopcroftMinimizer
public static FiniteAutomaton MinimizeDFA (
final StateContainer aNewStateContainer,
final StateContext aOriginalStates,
+ final Vector<Attribute> aAttributes,
final PrintStream aLog)
{
if (aLog != null)
@@ -95,7 +98,8 @@ public class HopcroftMinimizer
// Create and return the new minimized automaton.
return new FiniteAutomaton(
- aMinimizedStates);
+ aMinimizedStates,
+ aAttributes);
}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/NonValidatingCreator.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/NonValidatingCreator.java
index 2b7ec80..2801c51 100644
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/NonValidatingCreator.java
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/NonValidatingCreator.java
@@ -22,9 +22,6 @@
package org.apache.openoffice.ooxml.schema.automaton;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
import java.util.Vector;
import org.apache.openoffice.ooxml.schema.iterator.DereferencingNodeIterator;
@@ -42,24 +39,13 @@ import org.apache.openoffice.ooxml.schema.model.schema.SchemaBase;
* Input files but are not validated to conform to the schemas.
*/
public class NonValidatingCreator
+ extends CreatorBase
{
public NonValidatingCreator (
final SchemaBase aSchemaBase,
final File aLogFile)
{
- maSchemaBase = aSchemaBase;
- maStateContainer = new StateContainer();
-
- PrintStream aLog = null;
- try
- {
- aLog = new PrintStream(new FileOutputStream(aLogFile));
- }
- catch (FileNotFoundException e)
- {
- e.printStackTrace();
- }
- maLog = aLog;
+ super(aSchemaBase, aLogFile);
}
@@ -89,23 +75,40 @@ public class NonValidatingCreator
private FiniteAutomaton CreateForTopLevelElements (
final Iterable<Schema> aTopLevelSchemas)
{
+ AddComment("top level elements");
+ StartBlock();
final String sTypeName = "<top-level>";
final StateContext aStateContext = new StateContext(
maStateContainer,
sTypeName);
+ final State aStartState = aStateContext.GetStartState();
final State aEndState = aStateContext.CreateEndState();
// top level elements
for (final Schema aSchema : aTopLevelSchemas)
+ {
+ AddComment("schema %s", aSchema.GetShortName());
+ StartBlock();
for (final Element aElement : aSchema.TopLevelElements.GetSorted())
+ {
+ AddComment("Element: on '%s' go from %s to %s via %s",
+ aElement.GetElementName().GetDisplayName(),
+ aStartState.GetFullname(),
+ aEndState.GetFullname(),
+ aElement.GetTypeName().GetStateName());
+
aStateContext.GetStartState().AddTransition(
new Transition(
- aStateContext.GetStartState(),
+ aStartState,
aEndState,
aElement.GetElementName(),
aElement.GetTypeName().GetStateName()));
+ }
+ EndBlock();
+ }
+ EndBlock();
- return new FiniteAutomaton(aStateContext);
+ return new FiniteAutomaton(aStateContext, null);
}
@@ -113,12 +116,24 @@ public class NonValidatingCreator
private FiniteAutomaton CreateForComplexType (final ComplexType aComplexType)
{
+ maLog.printf("\n");
+ AddComment ("Complex Type %s defined in %s.",
+ aComplexType.GetName().GetDisplayName(),
+ aComplexType.GetLocation());
+ StartBlock();
+
final StateContext aStateContext = new StateContext(
maStateContainer,
aComplexType.GetName().GetStateName());
for (final Element aElement : CollectElements(aComplexType))
{
+ AddComment("Element: on '%s' go from %s to %s via %s",
+ aElement.GetElementName().GetDisplayName(),
+ aStateContext.GetStartState().GetFullname(),
+ aStateContext.GetStartState().GetFullname(),
+ aElement.GetTypeName().GetStateName());
+
aStateContext.GetStartState().AddTransition(
new Transition(
aStateContext.GetStartState(),
@@ -129,15 +144,23 @@ public class NonValidatingCreator
for (final Any aAny : CollectAnys(aComplexType))
{
- aStateContext.GetStartState().AddSkipData(
+ AddSkipTransition(
+ aStateContext.GetStartState(),
new SkipData(
aAny.GetProcessContentsFlag(),
aAny.GetNamespaces()));
}
+ // Collect all attributes.
+ maAttributes = new Vector<>();
+ for (final INode aNode : new DereferencingNodeIterator(aComplexType, maSchemaBase, true))
+ ProcessAttributes(aNode);
+
aStateContext.GetStartState().SetIsAccepting();
- return new FiniteAutomaton(aStateContext);
+ EndBlock();
+
+ return new FiniteAutomaton(aStateContext, maAttributes);
}
@@ -170,11 +193,4 @@ public class NonValidatingCreator
}
return aAnys;
}
-
-
-
-
- private final SchemaBase maSchemaBase;
- private final StateContainer maStateContainer;
- private final PrintStream maLog;
}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreator.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreator.java
index 00bf13d..8489299 100644
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreator.java
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreator.java
@@ -22,42 +22,57 @@
package org.apache.openoffice.ooxml.schema.automaton;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Iterator;
+import java.util.Stack;
import java.util.Vector;
+import org.apache.openoffice.ooxml.schema.iterator.DereferencingNodeIterator;
+import org.apache.openoffice.ooxml.schema.iterator.PermutationIterator;
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.INodeVisitor;
+import org.apache.openoffice.ooxml.schema.model.base.Location;
+import org.apache.openoffice.ooxml.schema.model.base.NodeVisitorAdapter;
+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.ComplexTypeReference;
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.SchemaBase;
+import org.apache.openoffice.ooxml.schema.model.simple.BuiltIn;
+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;
/** Create a set of validating stack automatons for a set of schemas.
* There is one DFA (deterministic finite automaton) for each complex type and
* one for the top level elements.
*/
public class ValidatingCreator
+ extends CreatorBase
+ implements INodeVisitor
{
public ValidatingCreator (
final SchemaBase aSchemaBase,
final File aLogFile)
{
- maSchemaBase = aSchemaBase;
- maStateContainer = new StateContainer();
-
- PrintStream aLog = null;
- try
- {
- aLog = new PrintStream(new FileOutputStream(aLogFile));
- }
- catch (FileNotFoundException e)
- {
- e.printStackTrace();
- }
- maLog = aLog;
+ super(aSchemaBase, aLogFile);
+ maContextStack = new Stack<>();
+ maCurrentContext = null;
}
@@ -89,29 +104,23 @@ public class ValidatingCreator
private FiniteAutomaton CreateForTopLevelElements ()
{
- final Map<State,Vector<Attribute>> aAttributes = new HashMap<>();
-
- final StateContext aStateContext = new StateContext(
+ maStateContext = new StateContext(
maStateContainer,
"<top-level>");
- final State aEndState = aStateContext.CreateEndState();
-
- final INodeVisitor aVisitor = new ValidatingCreatorVisitor(
- aAttributes,
- aStateContext,
- maSchemaBase,
- maLog,
- "",
- aStateContext.GetStartState(),
- aStateContext.GetStartState(),
- aEndState);
+ final State aEndState = maStateContext.CreateEndState();
+
+ assert(maContextStack.isEmpty());
+ msLogIndentation = "";
// top level elements
for (final Element aElement : maSchemaBase.TopLevelElements.GetSorted())
- aElement.AcceptVisitor(aVisitor);
-
- return new FiniteAutomaton(aStateContext);
+ ProcessType(
+ aElement,
+ maStateContext.GetStartState(),
+ maStateContext.GetStartState(),
+ aEndState);
+ return new FiniteAutomaton(maStateContext, null);
}
@@ -119,29 +128,641 @@ public class ValidatingCreator
private FiniteAutomaton CreateForComplexType (final ComplexType aComplexType)
{
- final Map<State,Vector<Attribute>> aAttributes = new HashMap<>();
-
- final StateContext aStateContext = new StateContext(
+ maStateContext = new StateContext(
maStateContainer,
aComplexType.GetName().GetStateName());
- final State aEndState = aStateContext.CreateEndState();
- aComplexType.AcceptVisitor(
- new ValidatingCreatorVisitor(
- aAttributes,
- aStateContext,
- maSchemaBase,
- maLog,
- "",
- aStateContext.GetStartState(),
- aStateContext.GetStartState(),
- aEndState));
- return new FiniteAutomaton(aStateContext);
+ maAttributes = new Vector<>();
+ final State aEndState = maStateContext.CreateEndState();
+ ProcessType(
+ aComplexType,
+ maStateContext.GetStartState(),
+ maStateContext.GetStartState(),
+ aEndState);
+ return new FiniteAutomaton(
+ maStateContext,
+ maAttributes);
+ }
+
+
+
+
+ @Override
+ public void Visit (final All aAll)
+ {
+ AddComment("All");
+ ProcessAttributes(aAll);
+
+ // Make a transformation of the children into a choice of sequences that
+ // can then be processed by already existing Visit() methods.
+ // These sequences enumerate all permutations of the original children.
+ final INode aReplacement = GetAllReplacement(aAll);
+
+ final State aLocalStartState = maStateContext.CreateState(
+ maCurrentContext.BaseState,
+ "As");
+ final State aLocalEndState = maStateContext.CreateState(
+ maCurrentContext.BaseState,
+ "Ae");
+
+ StartBlock();
+ AddEpsilonTransition(maCurrentContext.StartState, aLocalStartState);
+ ProcessType(
+ aReplacement,
+ maStateContext.CreateState(maCurrentContext.BaseState, "A"),
+ aLocalStartState,
+ aLocalEndState);
+ AddEpsilonTransition(aLocalEndState, maCurrentContext.EndState);
+ EndBlock();
+ }
+
+
+
+
+ @Override
+ public void Visit (final Any aAny)
+ {
+ assert(aAny.GetChildCount() == 0);
+
+ AddComment("Any");
+ ProcessAttributes(aAny);
+
+ AddSkipTransition(
+ maCurrentContext.StartState,
+ new SkipData(
+ aAny.GetProcessContentsFlag(),
+ aAny.GetNamespaces()));
+ AddEpsilonTransition(maCurrentContext.StartState, maCurrentContext.EndState);
+ }
+
+
+
+
+ @Override
+ public void Visit (final ComplexContent aComplexContent)
+ {
+ assert(aComplexContent.GetChildCount() == 1);
+
+ AddComment ("Complex Content.");
+ ProcessAttributes(aComplexContent);
+
+ StartBlock();
+ ProcessType(
+ aComplexContent.GetChildren().iterator().next(),
+ maCurrentContext.BaseState,
+ maCurrentContext.StartState,
+ maCurrentContext.EndState);
+ EndBlock();
+ }
+
+
+
+
+ @Override
+ public void Visit (final ComplexType aComplexType)
+ {
+ if (maLog != null)
+ {
+ maLog.print("\n");
+ AddComment ("Complex Type %s defined in %s.",
+ aComplexType.GetName().GetDisplayName(),
+ aComplexType.GetLocation());
+ }
+ ProcessAttributes(aComplexType);
+
+ StartBlock();
+ maLog.printf("%sstarting at state %s\n", msLogIndentation, maCurrentContext.StartState.GetFullname());
+
+ if (GetElementCount(aComplexType) == 0)
+ {
+ // There are elements. Therefore there will be no transitions.
+ // The start state is accepting and the end state is not necessary.
+ maCurrentContext.StartState.SetIsAccepting();
+ maStateContext.RemoveState(maCurrentContext.EndState);
+ }
+
+ for (final INode aChild : aComplexType.GetChildren())
+ ProcessType(aChild, maCurrentContext.BaseState, maCurrentContext.StartState, maCurrentContext.EndState);
+
+ EndBlock();
+ }
+
+
+
+
+ @Override
+ public void Visit (final ComplexTypeReference aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ @Override
+ public void Visit (final Choice aChoice)
+ {
+ AddComment("Choice");
+ ProcessAttributes(aChoice);
+
+ final State aLocalStartState = maStateContext.CreateState(maCurrentContext.BaseState, "Cs");
+ final State aLocalEndState = maStateContext.CreateState(maCurrentContext.BaseState, "Ce");
+ StartBlock();
+ AddEpsilonTransition(maCurrentContext.StartState, aLocalStartState);
+
+ int nStateIndex = 0;
+ for (final INode aChild : aChoice.GetChildren())
+ {
+ ProcessType(
+ aChild,
+ maStateContext.CreateState(maCurrentContext.BaseState, "C"+nStateIndex++),
+ aLocalStartState,
+ aLocalEndState);
+ }
+ AddEpsilonTransition(aLocalEndState, maCurrentContext.EndState);
+ EndBlock();
+ }
+
+
+
+
+ @Override
+ public void Visit (final Element aElement)
+ {
+ assert(aElement.GetChildCount()==0);
+
+ AddComment("Element: on '%s' go from %s to %s via %s",
+ aElement.GetElementName().GetDisplayName(),
+ maCurrentContext.StartState.GetFullname(),
+ maCurrentContext.EndState.GetFullname(),
+ aElement.GetTypeName().GetStateName());
+ ProcessAttributes(aElement);
+
+ final Transition aTransition = new Transition(
+ maCurrentContext.StartState,
+ maCurrentContext.EndState,
+ aElement.GetElementName(),
+ aElement.GetTypeName().GetStateName());
+ maCurrentContext.StartState.AddTransition(aTransition);
+ }
+
+
+
+
+ @Override
+ public void Visit (final ElementReference aReference)
+ {
+ assert(aReference.GetChildCount() == 0);
+
+ AddComment("Element reference to %s", aReference.GetReferencedElementName());
+ ProcessAttributes(aReference);
+
+ final Element aElement = aReference.GetReferencedElement(maSchemaBase);
+ if (aElement == null)
+ throw new RuntimeException("can't find referenced element "+aReference.GetReferencedElementName());
+ StartBlock();
+ ProcessType(aElement, maCurrentContext.BaseState, maCurrentContext.StartState, maCurrentContext.EndState);
+ EndBlock();
+ }
+
+
+
+
+ /** Treat extension nodes like sequences (for now).
+ */
+ @Override
+ public void Visit (final Extension aExtension)
+ {
+ assert(aExtension.GetChildCount() <= 1);
+
+ AddComment("Extension of base type %s", aExtension.GetBaseTypeName());
+ ProcessAttributes(aExtension);
+
+ final Vector<INode> aNodes = aExtension.GetTypeNodes(maSchemaBase);
+
+ StartBlock();
+ int nStateIndex = 0;
+ State aCurrentState = maStateContext.CreateState(maCurrentContext.BaseState, "E"+nStateIndex++);
+ AddEpsilonTransition(maCurrentContext.StartState, aCurrentState);
+
+ State aNextState = maStateContext.CreateState(maCurrentContext.BaseState, "E"+nStateIndex++);
+ ProcessType(aExtension.GetReferencedNode(maSchemaBase), aCurrentState, aCurrentState, aNextState);
+ aCurrentState = aNextState;
+
+ for (final INode aChild : aNodes)
+ {
+ aNextState = maStateContext.CreateState(maCurrentContext.BaseState, "E"+nStateIndex++);
+ ProcessType(aChild, aCurrentState, aCurrentState, aNextState);
+ aCurrentState = aNextState;
+ }
+ AddEpsilonTransition(aCurrentState, maCurrentContext.EndState);
+ EndBlock();
+ }
+
+
+
+
+ @Override
+ public void Visit (final Group aGroup)
+ {
+ assert(aGroup.GetChildCount() == 1);
+
+ AddComment("Group %s", aGroup.GetName());
+ ProcessAttributes(aGroup);
+
+ StartBlock();
+ final State aGroupBaseState = maStateContext.CreateState(maCurrentContext.BaseState, "G");
+ ProcessType(
+ aGroup.GetOnlyChild(),
+ aGroupBaseState,
+ maCurrentContext.StartState,
+ maCurrentContext.EndState);
+ EndBlock();
+ }
+
+
+
+
+ @Override
+ public void Visit (final GroupReference aReference)
+ {
+ AddComment("Group reference to %s", aReference.GetReferencedGroupName());
+ ProcessAttributes(aReference);
+
+ final Group aGroup = aReference.GetReferencedGroup(maSchemaBase);
+ if (aGroup == null)
+ throw new RuntimeException("can't find referenced group "+aReference.GetReferencedGroupName());
+
+ StartBlock();
+ ProcessType(aGroup, maCurrentContext.BaseState, maCurrentContext.StartState, maCurrentContext.EndState);
+ EndBlock();
+ }
+
+
+
+
+ /** An occurrence indicator defines how many times the single child can occur.
+ * The minimum value defines the mandatory number of times. The maximum value
+ * defines the optional number.
+ */
+ @Override
+ public void Visit (final OccurrenceIndicator aOccurrence)
+ {
+ assert(aOccurrence.GetChildCount() == 1);
+
+ AddComment("OccurrenceIndicator %s->%s",
+ aOccurrence.GetDisplayMinimum(),
+ aOccurrence.GetDisplayMaximum());
+ ProcessAttributes(aOccurrence);
+
+ StartBlock();
+
+ final INode aChild = aOccurrence.GetChildren().iterator().next();
+
+ int nIndex = 0;
+ State aCurrentState = maStateContext.CreateState(maCurrentContext.BaseState, "O"+nIndex++);
+ AddEpsilonTransition(maCurrentContext.StartState, aCurrentState);
+
+ if (aOccurrence.GetMinimum() == 0)
+ {
+ // A zero minimum means that all occurrences are optional.
+ // Add a short circuit from start to end.
+ AddComment("Occurrence: make whole element optional (min==0)");
+ AddEpsilonTransition(maCurrentContext.StartState, maCurrentContext.EndState);
+ }
+ else
+ {
+ // Write a row of mandatory transitions for the minimum.
+ for (; nIndex<=aOccurrence.GetMinimum(); ++nIndex)
+ {
+ // Add transition i-1 -> i (i == nIndex).
+ final State aNextState = maStateContext.CreateState(maCurrentContext.BaseState, "O"+nIndex);
+ AddComment("Occurrence: move from %d -> %d (%s -> %s) (minimum)",
+ nIndex-1,
+ nIndex,
+ aCurrentState,
+ aNextState);
+ StartBlock();
+ ProcessType(aChild, aCurrentState, aCurrentState, aNextState);
+ EndBlock();
+ aCurrentState = aNextState;
+ }
+ }
+
+ if (aOccurrence.GetMaximum() == OccurrenceIndicator.unbounded)
+ {
+ // Write loop on last state when max is unbounded.
+
+ // last -> loop
+ final State aLoopState = maStateContext.CreateState(maCurrentContext.BaseState, "OL");
+ AddComment("Occurrence: forward to loop (maximum)");
+ AddEpsilonTransition(aCurrentState, aLoopState);
+
+ // loop -> loop
+ AddComment("Occurrence: loop");
+ StartBlock();
+ ProcessType(aChild, aLoopState, aLoopState, aLoopState);
+ EndBlock();
+
+ // -> end
+ AddComment("Occurrence: forward to local end");
+ AddEpsilonTransition(aLoopState, maCurrentContext.EndState);
+ }
+ else
+ {
+ // Write a row of optional transitions for the maximum.
+ for (; nIndex<=aOccurrence.GetMaximum(); ++nIndex)
+ {
+ if (nIndex > 0)
+ {
+ // i-1 -> end
+ AddComment("Occurrence: make %d optional (maximum)", nIndex-1);
+ AddEpsilonTransition(aCurrentState, maCurrentContext.EndState);
+ }
+
+ // i-1 -> i
+ final State aNextState = maStateContext.CreateState(maCurrentContext.BaseState, "O"+nIndex);
+ AddComment("Occurrence: %d -> %d (%s -> %s) (maximum)",
+ nIndex-1,
+ nIndex,
+ aCurrentState,
+ aNextState);
+ StartBlock();
+ ProcessType(aChild, aCurrentState, aCurrentState, aNextState);
+ EndBlock();
+
+ aCurrentState = aNextState;
+ }
+
+ // max -> end
+ AddComment("Occurrence: forward to local end");
+ AddEpsilonTransition(aCurrentState, maCurrentContext.EndState);
+ }
+ EndBlock();
+ }
+
+
+
+
+ /** Ordered sequence of nodes.
+ * For n nodes create states S0 to Sn where Si and Si+1 become start and
+ * end states for the i-th child.
+ */
+ @Override
+ public void Visit (final Sequence aSequence)
+ {
+ AddComment("Sequence.");
+ ProcessAttributes(aSequence);
+
+ StartBlock();
+ int nStateIndex = 0;
+ State aCurrentState = maStateContext.CreateState(maCurrentContext.BaseState, "S"+nStateIndex++);
+ AddEpsilonTransition(maCurrentContext.StartState, aCurrentState);
+ for (final INode aChild : aSequence.GetChildren())
+ {
+ final State aNextState = maStateContext.CreateState(maCurrentContext.BaseState, "S"+nStateIndex++);
+ ProcessType(aChild, aCurrentState, aCurrentState, aNextState);
+ aCurrentState = aNextState;
+ }
+ AddEpsilonTransition(aCurrentState, maCurrentContext.EndState);
+ EndBlock();
+ }
+
+
+
+
+ @Override
+ public void Visit (final BuiltIn aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ @Override
+ public void Visit (final List aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ @Override
+ public void Visit (final Restriction aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+ @Override
+ public void Visit (final SimpleContent aNode)
+ {
+ AddComment("SimpleContent.");
+ ProcessAttributes(aNode);
+
+ for (final INode aChild : aNode.GetChildren())
+ ProcessType(aChild, maCurrentContext.BaseState, maCurrentContext.StartState, maCurrentContext.EndState);
+ }
+
+
+
+
+ @Override
+ public void Visit (final SimpleType aNode)
+ {
+ AddComment("SimpleContent.");
+ for (final INode aChild : aNode.GetChildren())
+ ProcessType(aChild, maCurrentContext.BaseState, maCurrentContext.StartState, maCurrentContext.EndState);
+ }
+
+
+
+
+ @Override
+ public void Visit (final SimpleTypeReference aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ @Override
+ public void Visit (final Union aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ @Override
+ public void Visit (final AttributeGroup aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ @Override
+ public void Visit (final AttributeReference aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ @Override
+ public void Visit (final Attribute aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ @Override
+ public void Visit (final AttributeGroupReference aNode)
+ {
+ throw new RuntimeException("can not handle "+aNode.toString());
+ }
+
+
+
+
+ private void ProcessType (
+ final INode aNode,
+ final State aBaseState,
+ final State aStartState,
+ final State aEndState)
+ {
+ maContextStack.push(maCurrentContext);
+ maCurrentContext = new Context(aBaseState, aStartState, aEndState);
+ aNode.AcceptVisitor(this);
+ maCurrentContext = maContextStack.pop();
+ }
+
+
+
+
+ private void AddEpsilonTransition (
+ final State aStartState,
+ final State aEndState)
+ {
+ // Silently ignore epsilon transitions from a state to itself.
+ // They may indicate a problem but usually are just artifacts
+ // that can be safely ignored.
+ if (aStartState == aEndState)
+ return;
+ else
+ {
+ final EpsilonTransition aTransition = new EpsilonTransition(
+ aStartState,
+ aEndState);
+ aStartState.AddEpsilonTransition(aTransition);
+
+ if (maLog != null)
+ {
+ maLog.printf("%sepsilon transition from %s to %s\n",
+ msLogIndentation,
+ aStartState.GetFullname(),
+ aEndState.GetFullname());
+ }
+ }
+ }
+
+
+
+
+ private int GetElementCount (final INode aNode)
+ {
+
+ class Visitor extends NodeVisitorAdapter
+ {
+ int nElementCount = 0;
+ @Override public void Visit (final Element aElement)
+ {
+ ++nElementCount;
+ }
+ int GetElementCount ()
+ {
+ return nElementCount;
+ }
+ };
+ final Visitor aVisitor = new Visitor();
+ for (final INode aChildNode : new DereferencingNodeIterator(aNode, maSchemaBase, false))
+ {
+ aChildNode.AcceptVisitor(aVisitor);
+ }
+ return aVisitor.GetElementCount();
+ }
+
+
+
+
+ private INode GetAllReplacement (final All aAll)
+ {
+ // By default each child of this node can appear exactly once, however
+ // the order is undefined. This corresponds to an enumeration of all
+ // permutations of the children.
+
+ // Set up an array of all children. This array will be modified to contain
+ // all permutations.
+ final INode[] aNodes = new INode[aAll.GetChildCount()];
+ final Iterator<INode> aChildren = aAll.GetChildren().iterator();
+ for (int nIndex=0; aChildren.hasNext(); ++nIndex)
+ aNodes[nIndex] = aChildren.next();
+
+ final Location aLocation = aAll.GetLocation();
+ final Choice aChoice = new Choice(aAll, aLocation);
+
+ // Treat every permutation as sequence so that the whole set of permutations
+ // is equivalent to a choice of sequences.
+ int nCount = 0;
+ for (final PermutationIterator<INode> aIterator = new PermutationIterator<>(aNodes); aIterator.HasMore(); aIterator.Next())
+ {
+ // Create a Sequence node for the current permutation and add it as
+ // choice to the Choice node.
+ final Sequence aSequence = new Sequence(aChoice, null, aLocation);
+ aChoice.AddChild(aSequence);
+
+ for (final INode aNode : aNodes)
+ aSequence.AddChild(aNode);
+
+ ++nCount;
+ }
+ System.out.printf("there are %d permutations\n", nCount);
+
+ return aChoice;
+ }
+
+
+
+
+ class Context
+ {
+ Context (
+ final State aBaseState,
+ final State aStartState,
+ final State aEndState)
+ {
+ BaseState = aBaseState;
+ StartState = aStartState;
+ EndState = aEndState;
+ }
+ final State BaseState;
+ final State StartState;
+ final State EndState;
}
- private final SchemaBase maSchemaBase;
- private final StateContainer maStateContainer;
- private final PrintStream maLog;
+ private StateContext maStateContext;
+ private final Stack<Context> maContextStack;
+ private Context maCurrentContext;
}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreatorVisitor.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreatorVisitor.java
deleted file mode 100644
index d374be1..0000000
--- a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/automaton/ValidatingCreatorVisitor.java
+++ /dev/null
@@ -1,646 +0,0 @@
-/**************************************************************
-*
-* 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.automaton;
-
-import java.io.PrintStream;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Vector;
-
-import org.apache.openoffice.ooxml.schema.iterator.AttributeIterator;
-import org.apache.openoffice.ooxml.schema.iterator.DereferencingNodeIterator;
-import org.apache.openoffice.ooxml.schema.iterator.PermutationIterator;
-import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
-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.NodeVisitorAdapter;
-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.SchemaBase;
-import org.apache.openoffice.ooxml.schema.model.simple.SimpleContent;
-
-/** A helper class of the ValidatingCreator.
- *
- * A visitor is called by the ValidatingCreator for each complex type.
- * Further instances are created and called while iterating over all nodes
- * of these types.
- */
-public class ValidatingCreatorVisitor
- extends NodeVisitorAdapter
-{
- public ValidatingCreatorVisitor (
- final Map<State,Vector<Attribute>> aAttributes,
- final StateContext aStateContext,
- final SchemaBase aSchemaBase,
- final PrintStream aLog,
- final String sLogIndentation,
- final State aBaseState,
- final State aStartState,
- final State aEndState)
- {
- maAttributes = aAttributes;
- maStateContext = aStateContext;
- maSchemaBase = aSchemaBase;
- maLog = aLog;
- msLogIndentation = sLogIndentation;
- maBaseState = aBaseState;
- maStartState = aStartState;
- maEndState = aEndState;
- }
-
-
-
-
- @Override
- public void Visit (final All aAll)
- {
- AddComment("All");
-
- // Make a transformation of the children into a choice of sequences that
- // can then be processed by already existing Visit() methods.
- // These sequences enumerate all permutations of the original children.
- final INode aReplacement = GetAllReplacement(aAll);
-
- final State aLocalStartState = maStateContext.CreateState(maBaseState, "As");
- final State aLocalEndState = maStateContext.CreateState(maBaseState, "Ae");
-
- StartBlock();
- AddEpsilonTransition(maStartState, aLocalStartState);
- ProcessType(
- aReplacement,
- maStateContext.CreateState(maBaseState, "A"),
- aLocalStartState,
- aLocalEndState);
- AddEpsilonTransition(aLocalEndState, maEndState);
- EndBlock();
- }
-
-
-
-
- @Override
- public void Visit (final Any aAny)
- {
- assert(aAny.GetChildCount() == 0);
-
- AddComment("Any");
- AddSkipTransition(
- maStartState,
- new SkipData(
- aAny.GetProcessContentsFlag(),
- aAny.GetNamespaces()));
- AddEpsilonTransition(maStartState, maEndState);
- }
-
-
-
-
- @Override
- public void Visit (final Choice aChoice)
- {
- AddComment("Choice");
-
- final State aLocalStartState = maStateContext.CreateState(maBaseState, "Cs");
- final State aLocalEndState = maStateContext.CreateState(maBaseState, "Ce");
- StartBlock();
- AddEpsilonTransition(maStartState, aLocalStartState);
-
- int nStateIndex = 0;
- for (final INode aChild : aChoice.GetChildren())
- {
- ProcessType(
- aChild,
- maStateContext.CreateState(maBaseState, "C"+nStateIndex++),
- aLocalStartState,
- aLocalEndState);
- }
- AddEpsilonTransition(aLocalEndState, maEndState);
- EndBlock();
- }
-
-
-
-
- @Override
- public void Visit (final ComplexContent aComplexContent)
- {
- assert(aComplexContent.GetChildCount() == 1);
-
- if (maLog != null)
- AddComment ("Complex Content.");
-
- StartBlock();
- ProcessType(
- aComplexContent.GetChildren().iterator().next(),
- maBaseState,
- maStartState,
- maEndState);
- EndBlock();
- }
-
-
-
-
- @Override
- public void Visit (final ComplexType aComplexType)
- {
- if (maLog != null)
- {
- maLog.print("\n");
- AddComment ("Complex Type %s defined in %s.",
- aComplexType.GetName().GetDisplayName(),
- aComplexType.GetLocation());
- }
-
- StartBlock();
- maLog.printf("%sstarting at state %s\n", msLogIndentation, maStartState.GetFullname());
- for (final Attribute aAttribute : new AttributeIterator(aComplexType, maSchemaBase))
- ProcessAttribute(aAttribute);
-
- if (GetElementCount(aComplexType) == 0)
- {
- // There are elements. Therefore there will be no transitions.
- // The start state is accepting and the end state is not necessary.
- maStartState.SetIsAccepting();
- maStateContext.RemoveState(maEndState);
- }
-
- for (final INode aChild : aComplexType.GetChildren())
- ProcessType(aChild, maBaseState, maStartState, maEndState);
-
- EndBlock();
- }
-
-
-
-
- @Override
- public void Visit (final Element aElement)
- {
- assert(aElement.GetChildCount()==0);
-
- AddComment("Element: on '%s' go from %s to %s via %s",
- aElement.GetElementName().GetDisplayName(),
- maStartState.GetFullname(),
- maEndState.GetFullname(),
- aElement.GetTypeName().GetStateName());
-
- final Transition aTransition = new Transition(
- maStartState,
- maEndState,
- aElement.GetElementName(),
- aElement.GetTypeName().GetStateName());
- maStartState.AddTransition(aTransition);
- }
-
-
-
-
- @Override
- public void Visit (final ElementReference aReference)
- {
- assert(aReference.GetChildCount() == 0);
-
- AddComment("Element reference to %s", aReference.GetReferencedElementName());
-
- final Element aElement = aReference.GetReferencedElement(maSchemaBase);
- if (aElement == null)
- throw new RuntimeException("can't find referenced element "+aReference.GetReferencedElementName());
- StartBlock();
- ProcessType(aElement, maBaseState, maStartState, maEndState);
- EndBlock();
- }
-
-
-
-
- /** Treat extension nodes like sequences (for now).
- */
- @Override
- public void Visit (final Extension aExtension)
- {
- assert(aExtension.GetChildCount() <= 1);
-
- AddComment("Extension of base type %s", aExtension.GetBaseTypeName());
-
- final Vector<INode> aNodes = aExtension.GetTypeNodes(maSchemaBase);
-
- StartBlock();
- int nStateIndex = 0;
- State aCurrentState = maStateContext.CreateState(maBaseState, "E"+nStateIndex++);
- AddEpsilonTransition(maStartState, aCurrentState);
- for (final INode aChild : aNodes)
- {
- final State aNextState = maStateContext.CreateState(maBaseState, "E"+nStateIndex++);
- ProcessType(aChild, aCurrentState, aCurrentState, aNextState);
- aCurrentState = aNextState;
- }
- AddEpsilonTransition(aCurrentState, maEndState);
- EndBlock();
- }
-
-
-
-
- @Override
- public void Visit (final Group aGroup)
- {
- assert(aGroup.GetChildCount() == 1);
-
- AddComment("Group %s", aGroup.GetName());
-
- StartBlock();
- final State aGroupBaseState = maStateContext.CreateState(maBaseState, "G");
- ProcessType(
- aGroup.GetOnlyChild(),
- aGroupBaseState,
- maStartState,
- maEndState);
- EndBlock();
- }
-
-
-
-
- @Override
- public void Visit (final GroupReference aReference)
- {
- AddComment("Group reference to %s", aReference.GetReferencedGroupName());
- final Group aGroup = aReference.GetReferencedGroup(maSchemaBase);
- if (aGroup == null)
- throw new RuntimeException("can't find referenced group "+aReference.GetReferencedGroupName());
- StartBlock();
- ProcessType(aGroup, maBaseState, maStartState, maEndState);
- EndBlock();
- }
-
-
-
-
- /** An occurrence indicator defines how many times the single child can occur.
- * The minimum value defines the mandatory number of times. The maximum value
- * defines the optional number.
- */
- @Override
- public void Visit (final OccurrenceIndicator aOccurrence)
- {
- assert(aOccurrence.GetChildCount() == 1);
-
- AddComment("OccurrenceIndicator %s->%s",
- aOccurrence.GetDisplayMinimum(),
- aOccurrence.GetDisplayMaximum());
- StartBlock();
-
- final INode aChild = aOccurrence.GetChildren().iterator().next();
-
- int nIndex = 0;
- State aCurrentState = maStateContext.CreateState(maBaseState, "O"+nIndex++);
- AddEpsilonTransition(maStartState, aCurrentState);
-
- if (aOccurrence.GetMinimum() == 0)
- {
- // A zero minimum means that all occurrences are optional.
- // Add a short circuit from start to end.
- AddComment("Occurrence: make whole element optional (min==0)");
- AddEpsilonTransition(maStartState, maEndState);
- }
- else
- {
- // Write a row of mandatory transitions for the minimum.
- for (; nIndex<=aOccurrence.GetMinimum(); ++nIndex)
- {
- // Add transition i-1 -> i (i == nIndex).
- final State aNextState = maStateContext.CreateState(maBaseState, "O"+nIndex);
- AddComment("Occurrence: move from %d -> %d (%s -> %s) (minimum)",
- nIndex-1,
- nIndex,
- aCurrentState,
- aNextState);
- StartBlock();
- ProcessType(aChild, aCurrentState, aCurrentState, aNextState);
- EndBlock();
- aCurrentState = aNextState;
- }
- }
-
- if (aOccurrence.GetMaximum() == OccurrenceIndicator.unbounded)
- {
- // Write loop on last state when max is unbounded.
-
- // last -> loop
- final State aLoopState = maStateContext.CreateState(maBaseState, "OL");
- AddComment("Occurrence: forward to loop (maximum)");
- AddEpsilonTransition(aCurrentState, aLoopState);
-
- // loop -> loop
- AddComment("Occurrence: loop");
- StartBlock();
- ProcessType(aChild, aLoopState, aLoopState, aLoopState);
- EndBlock();
-
- // -> end
- AddComment("Occurrence: forward to local end");
- AddEpsilonTransition(aLoopState, maEndState);
- }
- else
- {
- // Write a row of optional transitions for the maximum.
- for (; nIndex<=aOccurrence.GetMaximum(); ++nIndex)
- {
- if (nIndex > 0)
- {
- // i-1 -> end
- AddComment("Occurrence: make %d optional (maximum)", nIndex-1);
- AddEpsilonTransition(aCurrentState, maEndState);
- }
-
- // i-1 -> i
- final State aNextState = maStateContext.CreateState(maBaseState, "O"+nIndex);
- AddComment("Occurrence: %d -> %d (%s -> %s) (maximum)",
- nIndex-1,
- nIndex,
- aCurrentState,
- aNextState);
- StartBlock();
- ProcessType(aChild, aCurrentState, aCurrentState, aNextState);
- EndBlock();
-
- aCurrentState = aNextState;
- }
-
- // max -> end
- AddComment("Occurrence: forward to local end");
- AddEpsilonTransition(aCurrentState, maEndState);
- }
- EndBlock();
- }
-
-
-
-
- /** Ordered sequence of nodes.
- * For n nodes create states S0 to Sn where Si and Si+1 become start and
- * end states for the i-th child.
- */
- @Override
- public void Visit (final Sequence aSequence)
- {
- AddComment("Sequence.");
-
- StartBlock();
- int nStateIndex = 0;
- State aCurrentState = maStateContext.CreateState(maBaseState, "S"+nStateIndex++);
- AddEpsilonTransition(maStartState, aCurrentState);
- for (final INode aChild : aSequence.GetChildren())
- {
- final State aNextState = maStateContext.CreateState(maBaseState, "S"+nStateIndex++);
- ProcessType(aChild, aCurrentState, aCurrentState, aNextState);
- aCurrentState = aNextState;
- }
- AddEpsilonTransition(aCurrentState, maEndState);
- EndBlock();
- }
-
-
-
-
- @Override
- public void Visit (final SimpleContent aSimpleContent)
- {
- AddComment("SimpleContent.");
- }
-
-
-
-
- @Override
- public void Default (final INode aNode)
- {
- throw new RuntimeException("can not handle "+aNode.toString());
- }
-
-
-
-
- private void ProcessType (
- final INode aNode,
- final State aBaseState,
- final State aStartState,
- final State aEndState)
- {
- aNode.AcceptVisitor(
- new ValidatingCreatorVisitor(
- maAttributes,
- maStateContext,
- maSchemaBase,
- maLog,
- msLogIndentation,
- aBaseState,
- aStartState,
- aEndState));
- }
-
-
-
-
- private void ProcessAttribute (
- final Attribute aAttribute)
- {
- Vector<Attribute> aAttributes = maAttributes.get(maStartState);
- if (aAttributes == null)
- {
- aAttributes = new Vector<>();
- maAttributes.put(maStartState, aAttributes);
- }
- aAttributes.add(aAttribute);
-
- if (maLog != null)
- maLog.printf("%sattribute %s\n", msLogIndentation, aAttribute.toString());
- }
-
-
-
-
- private void AddEpsilonTransition (
- final State aStartState,
- final State aEndState)
- {
- // Silently ignore epsilon transitions from a state to itself.
- // They may indicate a problem but usually are just artifacts
- // that can be safely ignored.
- if (aStartState == aEndState)
- return;
- else
- {
- final EpsilonTransition aTransition = new EpsilonTransition(
- aStartState,
- aEndState);
- aStartState.AddEpsilonTransition(aTransition);
-
- if (maLog != null)
- {
- maLog.printf("%sepsilon transition from %s to %s\n",
- msLogIndentation,
- aStartState.GetFullname(),
- aEndState.GetFullname());
- }
- }
- }
-
-
-
-
- private void AddSkipTransition (
- final State aState,
- final SkipData aSkipData)
- {
- aState.AddSkipData(aSkipData);
-
- if (maLog != null)
- {
- maLog.printf("%sskip state %s\n",
- msLogIndentation,
- aState.GetFullname());
- }
- }
-
-
-
-
- private void AddComment (
- final String sFormat,
- final Object ... aArgumentList)
- {
- if (maLog != null)
- {
- maLog.print(msLogIndentation);
- maLog.print("// ");
- maLog.printf(sFormat, aArgumentList);
- maLog.print("\n");
- }
- }
-
-
-
-
- private void StartBlock ()
- {
- if (maLog != null)
- msLogIndentation += " ";
- }
-
-
-
-
- private void EndBlock ()
- {
- if (maLog != null)
- msLogIndentation = msLogIndentation.substring(4);
- }
-
-
-
-
- private int GetElementCount (final INode aNode)
- {
-
- class Visitor extends NodeVisitorAdapter
- {
- int nElementCount = 0;
- @Override public void Visit (final Element aElement)
- {
- ++nElementCount;
- }
- int GetElementCount ()
- {
- return nElementCount;
- }
- };
- final Visitor aVisitor = new Visitor();
- for (final INode aChildNode : new DereferencingNodeIterator(aNode, maSchemaBase, false))
- {
- aChildNode.AcceptVisitor(aVisitor);
- }
- return aVisitor.GetElementCount();
- }
-
-
-
-
- private INode GetAllReplacement (final All aAll)
- {
- // By default each child of this node can appear exactly once, however
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list