summaryrefslogtreecommitdiff
path: root/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2014-07-14 19:09:11 +0000
committerArmin Le Grand <alg@apache.org>2014-07-14 19:09:11 +0000
commit3c1d4742e649fe9c8aed8c2817fe3e1f3364f298 (patch)
treee0c6e02c89aa9227726c9469da1001b3e29c41df /ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator
parentc5c31e2aeaedbdf76e1f38d3c385e34f5ed875ca (diff)
Resync to trunk, windows non-pro buildaoo/aw080
Diffstat (limited to 'ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator')
-rw-r--r--ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/LogGenerator.java313
-rw-r--r--ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/ParserTablesGenerator.java555
-rw-r--r--ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/HtmlGenerator.java623
-rw-r--r--ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/code.js442
-rw-r--r--ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/display.css57
-rw-r--r--ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/linking-template.html22
-rw-r--r--ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/template.html24
7 files changed, 2036 insertions, 0 deletions
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/LogGenerator.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/LogGenerator.java
new file mode 100644
index 000000000000..36deab269b96
--- /dev/null
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/LogGenerator.java
@@ -0,0 +1,313 @@
+/**************************************************************
+*
+* 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.generator;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
+import java.util.Map.Entry;
+
+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.Node;
+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.schema.Schema;
+import org.apache.openoffice.ooxml.schema.model.schema.SchemaBase;
+import org.apache.openoffice.ooxml.schema.model.simple.Restriction;
+import org.apache.openoffice.ooxml.schema.model.simple.SimpleType;
+import org.apache.openoffice.ooxml.schema.model.simple.SimpleTypeReference;
+
+public class LogGenerator
+{
+ public static void Write (
+ final File aOutputFile,
+ final SchemaBase aSchemaBase,
+ final Iterable<Schema> aTopLevelSchemas)
+ {
+ final long nStartTime = System.currentTimeMillis();
+
+ try
+ {
+ final LogGenerator aGenerator = new LogGenerator(
+ new PrintStream(aOutputFile),
+ aSchemaBase);
+
+ aGenerator.WriteNamespaces(aSchemaBase);
+ aGenerator.WriteTopLevelElements(aTopLevelSchemas);
+ aGenerator.WriteComplexTypes(aSchemaBase);
+ aGenerator.WriteGroups(aSchemaBase);
+ aGenerator.WriteSimpleTypes(aSchemaBase);
+ aGenerator.WriteAttributeGroups(aSchemaBase);
+ aGenerator.WriteAttributes(aSchemaBase);
+ }
+ catch (final FileNotFoundException aException)
+ {
+ aException.printStackTrace();
+ }
+
+ final long nEndTime = System.currentTimeMillis();
+ System.out.printf("wrote log output to '%s' in %fs\n",
+ aOutputFile.toString(),
+ (nEndTime-nStartTime)/1000.0f);
+ }
+
+
+
+
+ private LogGenerator (
+ final PrintStream aOut,
+ final SchemaBase aSchemaBase)
+ {
+ maSchemaBase = aSchemaBase;
+ maOut = aOut;
+ }
+
+
+
+
+ private void WriteComment (final String sFormat, final Object ... aArgumentList)
+ {
+ maOut.printf("// "+sFormat+"\n", aArgumentList);
+ }
+
+
+
+
+ private void WriteNamespaces (final SchemaBase aSchema)
+ {
+ // Write namespace definitions.
+ WriteComment("%d Namespaces.", aSchema.Namespaces.GetCount());
+ for (final Entry<String,String> aEntry : aSchema.Namespaces.GetSorted())
+ {
+ maOut.printf(" %s -> %s\n",
+ aEntry.getValue()==null ? "<no-prefix>" : aEntry.getValue(),
+ aEntry.getKey());
+ }
+ }
+
+
+
+ private void WriteTopLevelElements (final Iterable<Schema> aTopLevelSchemas)
+ {
+ // Write top level elements.
+ WriteComment("Top-level elements.");
+ for (final Schema aSchema : aTopLevelSchemas)
+ {
+ WriteComment(" Schema %s.", aSchema.GetShortName());
+ for (final Element aElement : aSchema.TopLevelElements.GetSorted())
+ maOut.printf(" \"%s\" -> %s\n",
+ aElement.GetElementName().GetDisplayName(),
+ aElement.GetTypeName().GetDisplayName());
+ }
+ }
+
+
+
+
+ private void WriteComplexTypes (final SchemaBase aSchema)
+ {
+ WriteComment(" %d Complex Types.", aSchema.ComplexTypes.GetCount());
+ for (final ComplexType aType : aSchema.ComplexTypes.GetSorted())
+ {
+ WriteType(" ", aType, true);
+ }
+ }
+
+
+
+
+ private void WriteSimpleTypes (final SchemaBase aSchema)
+ {
+ WriteComment(" %d Simple Types.", aSchema.SimpleTypes.GetCount());
+ for (final SimpleType aType : aSchema.SimpleTypes.GetSorted())
+ {
+ WriteType(" ", aType, true);
+ }
+ }
+
+
+
+
+ private void WriteGroups (final SchemaBase aSchema)
+ {
+ WriteComment(" %d Groups.", aSchema.Groups.GetCount());
+ for (final Node aType : aSchema.Groups.GetSorted())
+ {
+ WriteType(" ", aType, true);
+ }
+ }
+
+
+
+
+ private void WriteAttributeGroups (final SchemaBase aSchema)
+ {
+ WriteComment(" %d Attribute Groups.", aSchema.AttributeGroups.GetCount());
+ for (final Node aType : aSchema.AttributeGroups.GetSorted())
+ {
+ WriteType(" ", aType, true);
+ }
+ }
+
+
+
+
+ private void WriteAttributes (final SchemaBase aSchema)
+ {
+ WriteComment(" %d Attributes.", aSchema.Attributes.GetCount());
+ for (final Node aType : aSchema.Attributes.GetSorted())
+ {
+ WriteType(" ", aType, true);
+ }
+ }
+
+
+
+
+ private void WriteType (
+ final String sIndentation,
+ final INode aType,
+ final boolean bIsTopLevel)
+ {
+ maOut.printf("%s%s", sIndentation, aType.toString());
+
+ if (bIsTopLevel)
+ {
+ final Node aNode = (Node)aType;
+ maOut.printf(" defined at %s",
+ aNode.GetLocation());
+ }
+ if ( ! HasChild(aType))
+ {
+ maOut.printf(" {}\n");
+ }
+ else
+ {
+ maOut.printf(" {\n");
+
+ // Write attributes.
+ switch(aType.GetNodeType())
+ {
+ case ComplexType:
+ for (final INode aAttribute : ((ComplexType)aType).GetAttributes())
+ WriteAttribute(sIndentation+" ", aAttribute);
+ break;
+
+ case SimpleTypeReference:
+ WriteType(
+ sIndentation+" ",
+ ((SimpleTypeReference)aType).GetReferencedSimpleType(maSchemaBase),
+ false);
+ break;
+
+ default:
+ break;
+ }
+
+
+ // Write child types.
+ for (final INode aChild : aType.GetChildren())
+ WriteType(sIndentation+" ", aChild, false);
+
+ maOut.printf("%s}\n", sIndentation);
+ }
+ }
+
+
+
+
+ private void WriteAttribute (
+ final String sIndentation,
+ final INode aAttribute)
+ {
+ switch(aAttribute.GetNodeType())
+ {
+ case Attribute:
+ maOut.printf(
+ "%sattribute %s of type %s\n",
+ sIndentation,
+ ((Attribute)aAttribute).GetName().GetDisplayName(),
+ ((Attribute)aAttribute).GetTypeName().GetDisplayName());
+ break;
+
+ case AttributeGroup:
+ maOut.printf(
+ "%sattribute group %s {\n",
+ sIndentation,
+ ((AttributeGroup)aAttribute).GetName().GetDisplayName());
+ for (final INode aChildAttribute : ((AttributeGroup)aAttribute).GetChildren())
+ WriteAttribute(sIndentation+" ", aChildAttribute);
+ maOut.printf("%s}\n", sIndentation);
+ break;
+ case AttributeGroupReference:
+ maOut.printf(
+ "%sreference to attribute group %s {\n",
+ sIndentation,
+ ((AttributeGroupReference)aAttribute).GetReferencedName().GetDisplayName());
+ WriteAttribute(sIndentation+" ", ((AttributeGroupReference)aAttribute).GetReferencedAttributeGroup(maSchemaBase));
+ maOut.printf("%s}\n", sIndentation);
+ break;
+
+ case AttributeReference:
+ maOut.printf(
+ "%sreference to attribute %s {\n",
+ sIndentation,
+ ((AttributeReference)aAttribute).GetReferencedName().GetDisplayName());
+ WriteAttribute(sIndentation+" ", ((AttributeReference)aAttribute).GetReferencedAttribute(maSchemaBase));
+ maOut.printf("%s}\n", sIndentation);
+ break;
+ default:
+ throw new RuntimeException();
+ }
+ }
+
+
+
+
+ private boolean HasChild (final INode aType)
+ {
+ if (aType.GetChildren().iterator().hasNext())
+ return true;
+
+ switch (aType.GetNodeType())
+ {
+ case ComplexType:
+ return ((ComplexType)aType).GetAttributes().iterator().hasNext();
+
+ case SimpleTypeReference:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+
+
+
+ private final SchemaBase maSchemaBase;
+ private final PrintStream maOut;
+}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/ParserTablesGenerator.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/ParserTablesGenerator.java
new file mode 100644
index 000000000000..99cfbe1161bb
--- /dev/null
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/ParserTablesGenerator.java
@@ -0,0 +1,555 @@
+/**************************************************************
+*
+* 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.generator;
+
+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.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.openoffice.ooxml.schema.automaton.FiniteAutomaton;
+import org.apache.openoffice.ooxml.schema.automaton.FiniteAutomatonContainer;
+import org.apache.openoffice.ooxml.schema.automaton.SkipData;
+import org.apache.openoffice.ooxml.schema.automaton.State;
+import org.apache.openoffice.ooxml.schema.automaton.Transition;
+import org.apache.openoffice.ooxml.schema.model.attribute.Attribute;
+import org.apache.openoffice.ooxml.schema.model.attribute.AttributeBase.Use;
+import org.apache.openoffice.ooxml.schema.model.base.INode;
+import org.apache.openoffice.ooxml.schema.model.base.QualifiedName;
+import org.apache.openoffice.ooxml.schema.model.schema.NamespaceMap;
+import org.apache.openoffice.ooxml.schema.parser.FormDefault;
+import org.apache.openoffice.ooxml.schema.simple.BlobNode;
+import org.apache.openoffice.ooxml.schema.simple.DateTimeNode;
+import org.apache.openoffice.ooxml.schema.simple.ISimpleTypeNode;
+import org.apache.openoffice.ooxml.schema.simple.ISimpleTypeNodeVisitor;
+import org.apache.openoffice.ooxml.schema.simple.NumberNode;
+import org.apache.openoffice.ooxml.schema.simple.SimpleTypeContainer;
+import org.apache.openoffice.ooxml.schema.simple.SimpleTypeDescriptor;
+import org.apache.openoffice.ooxml.schema.simple.StringNode;
+import org.apache.openoffice.ooxml.schema.simple.UnionNode;
+
+public class ParserTablesGenerator
+{
+ public ParserTablesGenerator (
+ final FiniteAutomatonContainer aAutomatons,
+ final NamespaceMap aNamespaces,
+ final SimpleTypeContainer aSimpleTypes,
+ final Map<String,Integer> aAttributeValueToIdMap)
+ {
+ maAutomatons = aAutomatons;
+ maSimpleTypes = aSimpleTypes;
+ maNamespaces = aNamespaces;
+ maNameToIdMap = new TreeMap<>();
+ maPrefixToIdMap = new HashMap<>();
+ maTypeNameToIdMap = new TreeMap<>();
+ maAttributeValueToIdMap = aAttributeValueToIdMap;
+ }
+
+
+
+
+ public void Generate (
+ final File aParseTableFile)
+ {
+ final long nStartTime = System.currentTimeMillis();
+
+ SetupNameList();
+ AssignNameIds();
+
+ try
+ {
+ final PrintStream aOut = new PrintStream(new FileOutputStream(aParseTableFile));
+
+ WriteNamespaceList(aOut);
+ WriteNameList(aOut);
+ WriteGlobalStartEndStates(aOut);
+ WriteAutomatonList(aOut);
+ WriteSimpleTypes(aOut);
+ WriteAttributeValues(aOut);
+ aOut.close();
+ }
+ catch (final FileNotFoundException aException)
+ {
+ aException.printStackTrace();
+ }
+
+ final long nEndTime = System.currentTimeMillis();
+ System.out.printf("wrote parse tables to %s in %fs\n",
+ aParseTableFile.toString(),
+ (nEndTime-nStartTime)/1000.0);
+ }
+
+
+
+
+ private void SetupNameList ()
+ {
+ final Set<String> aNames = new TreeSet<>();
+
+ // Add the element names.
+ for (final FiniteAutomaton aAutomaton : maAutomatons.GetAutomatons())
+ for (final Transition aTransition : aAutomaton.GetTransitions())
+ {
+ if (aTransition.GetElementName() == null)
+ throw new RuntimeException();
+ aNames.add(aTransition.GetElementName().GetLocalPart());
+ }
+
+ // Add the attribute names.
+ for (final FiniteAutomaton aAutomaton : maAutomatons.GetAutomatons())
+ for (final Attribute aAttribute : aAutomaton.GetAttributes())
+ aNames.add(aAttribute.GetName().GetLocalPart());
+
+ // Create unique ids for the names.
+ int nIndex = 1;
+ maNameToIdMap.clear();
+ for (final String sName : aNames)
+ maNameToIdMap.put(sName, nIndex++);
+
+ // Create unique ids for namespace prefixes.
+ nIndex = 1;
+ maPrefixToIdMap.clear();
+ for (final Entry<String, String> aEntry : maNamespaces)
+ {
+ maPrefixToIdMap.put(aEntry.getValue(), nIndex++);
+ }
+ }
+
+
+
+
+ /** During the largest part of the parsing process, states and elements are
+ * identified not via their name but via a unique id.
+ * That allows a fast lookup.
+ */
+ private void AssignNameIds ()
+ {
+ maTypeNameToIdMap.clear();
+ int nIndex = 0;
+
+ // Process state names.
+ final Set<QualifiedName> aSortedTypeNames = new TreeSet<>();
+ for (final State aState : maAutomatons.GetStates())
+ aSortedTypeNames.add(aState.GetQualifiedName());
+ for (final Entry<String, SimpleTypeDescriptor> aSimpleType : maSimpleTypes.GetSimpleTypes())
+ aSortedTypeNames.add(aSimpleType.getValue().GetName());
+
+ for (final QualifiedName aName : aSortedTypeNames)
+ maTypeNameToIdMap.put(aName.GetStateName(), nIndex++);
+ }
+
+
+
+
+ private void WriteNamespaceList (final PrintStream aOut)
+ {
+ aOut.printf("# namespaces\n");
+ for (final Entry<String, String> aEntry : maNamespaces)
+ {
+ aOut.printf("namespace %-8s %2d %s\n",
+ aEntry.getValue(),
+ maPrefixToIdMap.get(aEntry.getValue()),
+ aEntry.getKey());
+ }
+ }
+
+
+
+
+ private void WriteGlobalStartEndStates (final PrintStream aOut)
+ {
+ aOut.printf("\n# start and end states\n");
+
+ final FiniteAutomaton aAutomaton = maAutomatons.GetTopLevelAutomaton();
+ final State aStartState = aAutomaton.GetStartState();
+ aOut.printf("start-state %4d %s\n",
+ maTypeNameToIdMap.get(aStartState.GetFullname()),
+ aStartState.GetFullname());
+ for (final State aAcceptingState : aAutomaton.GetAcceptingStates())
+ aOut.printf("end-state %4d %s\n",
+ maTypeNameToIdMap.get(aAcceptingState.GetFullname()),
+ aAcceptingState.GetFullname());
+ }
+
+
+
+
+ private void WriteNameList (final PrintStream aOut)
+ {
+ aOut.printf("\n# %d names\n", maNameToIdMap.size());
+ for (final Entry<String, Integer> aEntry : maNameToIdMap.entrySet())
+ {
+ aOut.printf("name %4d %s\n",
+ aEntry.getValue(),
+ aEntry.getKey());
+ }
+
+ aOut.printf("\n# %s states\n", maTypeNameToIdMap.size());
+ for (final Entry<String, Integer> aEntry : maTypeNameToIdMap.entrySet())
+ {
+ aOut.printf("state-name %4d %s\n",
+ aEntry.getValue(),
+ aEntry.getKey());
+ }
+ }
+
+
+
+
+ private void WriteAutomatonList (final PrintStream aOut)
+ {
+ for (final FiniteAutomaton aAutomaton : maAutomatons.GetAutomatons())
+ {
+ aOut.printf("# %s at %s\n", aAutomaton.GetTypeName(), aAutomaton.GetLocation());
+
+ final State aStartState = aAutomaton.GetStartState();
+ final int nStartStateId = maTypeNameToIdMap.get(aStartState.GetFullname());
+
+ // Write start state.
+ aOut.printf("start-state %d %s\n",
+ nStartStateId,
+ aStartState);
+
+ // Write accepting states.
+ for (final State aState : aAutomaton.GetAcceptingStates())
+ {
+ aOut.printf("accepting-state %d %s\n",
+ maTypeNameToIdMap.get(aState.GetFullname()),
+ aState.GetFullname());
+ }
+
+ // Write text type.
+ final INode aTextType = aStartState.GetTextType();
+ if (aTextType != null)
+ {
+ switch(aTextType.GetNodeType())
+ {
+ case BuiltIn:
+ aOut.printf("text-type %d %d %s\n",
+ nStartStateId,
+ maTypeNameToIdMap.get(aTextType.GetName().GetStateName()),
+ aTextType.GetName().GetStateName());
+ break;
+ case SimpleType:
+ aOut.printf("text-type %d %d %s\n",
+ nStartStateId,
+ maTypeNameToIdMap.get(aTextType.GetName().GetStateName()),
+ aTextType.GetName().GetStateName());
+ break;
+ default:
+ throw new RuntimeException();
+ }
+ }
+
+ WriteAttributes(
+ aOut,
+ aStartState,
+ aAutomaton.GetAttributes());
+
+ // Write transitions.
+ for (final Transition aTransition : aAutomaton.GetTransitions())
+ {
+ final Integer nId = maTypeNameToIdMap.get(aTransition.GetElementTypeName());
+ aOut.printf("transition %4d %4d %2d %4d %4d %s %s %s %s\n",
+ maTypeNameToIdMap.get(aTransition.GetStartState().GetFullname()),
+ maTypeNameToIdMap.get(aTransition.GetEndState().GetFullname()),
+ maPrefixToIdMap.get(aTransition.GetElementName().GetNamespacePrefix()),
+ maNameToIdMap.get(aTransition.GetElementName().GetLocalPart()),
+ nId!=null ? nId : -1,
+ aTransition.GetStartState().GetFullname(),
+ aTransition.GetEndState().GetFullname(),
+ aTransition.GetElementName().GetStateName(),
+ aTransition.GetElementTypeName());
+ }
+ // Write skip data.
+ for (final State aState : aAutomaton.GetStates())
+ {
+ for (@SuppressWarnings("unused") final SkipData aSkipData : aState.GetSkipData())
+ aOut.printf("skip %4d %s\n",
+ maTypeNameToIdMap.get(aState.GetFullname()),
+ aState.GetFullname());
+ }
+ }
+ }
+
+
+
+
+ private void WriteAttributes (
+ final PrintStream aOut,
+ final State aState,
+ final Iterable<Attribute> aAttributes)
+ {
+ // Write attributes.
+ for (final Attribute aAttribute : aAttributes)
+ {
+ aOut.printf("attribute %4d %2d %c %4d %4d %s %s %s %s %s\n",
+ maTypeNameToIdMap.get(aState.GetFullname()),
+ maPrefixToIdMap.get(aAttribute.GetName().GetNamespacePrefix()),
+ aAttribute.GetFormDefault()==FormDefault.qualified ? 'q' : 'u',
+ maNameToIdMap.get(aAttribute.GetName().GetLocalPart()),
+ maTypeNameToIdMap.get(aAttribute.GetTypeName().GetStateName()),
+ aAttribute.GetUse()==Use.Optional ? 'o' : 'u',
+ aAttribute.GetDefault()==null ? "null" : '"'+aAttribute.GetDefault()+'"',
+ aState.GetFullname(),
+ aAttribute.GetName().GetStateName(),
+ aAttribute.GetTypeName().GetStateName());
+ }
+ }
+
+
+
+
+ private void WriteSimpleTypes (
+ final PrintStream aOut)
+ {
+ if (maSimpleTypes == null)
+ {
+ aOut.printf("\n// There is no simple type information.\n");
+ }
+ else
+ {
+ aOut.printf("\n// %d simple types.\n", maSimpleTypes.GetSimpleTypeCount());
+ for (final Entry<String,SimpleTypeDescriptor> aEntry : maSimpleTypes.GetSimpleTypesSorted())
+ {
+ int nIndex = 0;
+ for (final ISimpleTypeNode aSubType : aEntry.getValue().GetSubType())
+ {
+ final int nCurrentIndex = nIndex++;
+
+ final StringBuffer aLine = new StringBuffer();
+ aLine.append(String.format(
+ "simple-type %5d %1d %c ",
+ maTypeNameToIdMap.get(aEntry.getKey()),
+ nCurrentIndex,
+ aSubType.IsList() ? 'L' : 'T'));
+
+ aSubType.AcceptVisitor(new ISimpleTypeNodeVisitor()
+ {
+ @Override public void Visit(UnionNode aType)
+ {
+ throw new RuntimeException("unexpected");
+ }
+ @Override public void Visit(StringNode aType)
+ {
+ AppendStringDescription(aLine, aType);
+ }
+ @Override public void Visit(NumberNode<?> aType)
+ {
+ AppendNumberDescription(aLine, aType);
+ }
+ @Override public void Visit(DateTimeNode aType)
+ {
+ AppendDateTimeDescription(aLine, aType);
+ }
+ @Override public void Visit(BlobNode aType)
+ {
+ AppendBlobDescription(aLine, aType);
+ }
+ });
+ aOut.printf("%s\n", aLine.toString());
+ }
+ }
+ }
+ }
+
+
+
+
+ private void WriteAttributeValues (
+ final PrintStream aOut)
+ {
+ final Map<String,Integer> aSortedMap = new TreeMap<>();
+ aSortedMap.putAll(maAttributeValueToIdMap);
+ aOut.printf("// %d attribute values from enumerations.\n", maAttributeValueToIdMap.size());
+ for (final Entry<String,Integer> aEntry : aSortedMap.entrySet())
+ aOut.printf("attribute-value %5d %s\n", aEntry.getValue(), QuoteString(aEntry.getKey()));
+ }
+
+
+
+
+ private static void AppendStringDescription (
+ final StringBuffer aLine,
+ final StringNode aType)
+ {
+ aLine.append("S ");
+ switch(aType.GetRestrictionType())
+ {
+ case Enumeration:
+ aLine.append('E');
+ for (final int nValueId : aType.GetEnumerationRestriction())
+ {
+ aLine.append(' ');
+ aLine.append(nValueId);
+ }
+ break;
+ case Pattern:
+ aLine.append("P ");
+ aLine.append(QuoteString(aType.GetPatternRestriction()));
+ break;
+ case Length:
+ aLine.append("L ");
+ final int[] aLengthRestriction = aType.GetLengthRestriction();
+ aLine.append(aLengthRestriction[0]);
+ aLine.append(' ');
+ aLine.append(aLengthRestriction[1]);
+ break;
+ case None:
+ aLine.append('N');
+ break;
+ default:
+ throw new RuntimeException();
+ }
+ }
+
+
+
+
+ private static void AppendNumberDescription (
+ final StringBuffer aLine,
+ final NumberNode<?> aType)
+ {
+ aLine.append("N ");
+ switch(aType.GetNumberType())
+ {
+ case Boolean: aLine.append("u1"); break;
+ case Byte: aLine.append("s8"); break;
+ case UnsignedByte: aLine.append("u8"); break;
+ case Short: aLine.append("s16"); break;
+ case UnsignedShort: aLine.append("u16"); break;
+ case Int: aLine.append("s32"); break;
+ case UnsignedInt: aLine.append("u32"); break;
+ case Long: aLine.append("s64"); break;
+ case UnsignedLong: aLine.append("u64"); break;
+ case Integer: aLine.append("s*"); break;
+ case Float: aLine.append("f"); break;
+ case Double: aLine.append("d"); break;
+ default:
+ throw new RuntimeException("unsupported numerical type "+aType.GetNumberType());
+ }
+ aLine.append(' ');
+ switch(aType.GetRestrictionType())
+ {
+ case Enumeration:
+ aLine.append("E ");
+ for (final Object nValue : aType.GetEnumerationRestriction())
+ {
+ aLine.append(" ");
+ aLine.append(nValue);
+ }
+ break;
+ case Size:
+ aLine.append("S");
+ if (aType.GetMinimum() != null)
+ {
+ if (aType.IsMinimumInclusive())
+ aLine.append(" >= ");
+ else
+ aLine.append(" > ");
+ aLine.append(aType.GetMinimum());
+ }
+ if (aType.GetMaximum() != null)
+ {
+ if (aType.IsMaximumInclusive())
+ aLine.append(" <= ");
+ else
+ aLine.append(" < ");
+ aLine.append(aType.GetMaximum());
+ }
+ break;
+ case None:
+ aLine.append("N");
+ break;
+ default:
+ throw new RuntimeException("unsupported numerical restriction "+aType.GetRestrictionType());
+ }
+ }
+
+
+
+
+ private static void AppendDateTimeDescription (
+ final StringBuffer aLine,
+ final DateTimeNode aType)
+ {
+ aLine.append("D");
+ }
+
+
+
+
+ private static void AppendBlobDescription (
+ final StringBuffer aLine,
+ final BlobNode aType)
+ {
+ aLine.append("B ");
+ switch(aType.GetBlobType())
+ {
+ case Base64Binary:
+ aLine.append("B ");
+ break;
+ case HexBinary:
+ aLine.append ("H ");
+ break;
+ default:
+ throw new RuntimeException("unsupported blob type");
+ }
+ switch(aType.GetRestrictionType())
+ {
+ case Length:
+ aLine.append("L ");
+ aLine.append(aType.GetLengthRestriction());
+ break;
+ case None:
+ aLine.append("N");
+ break;
+ default:
+ throw new RuntimeException();
+ }
+ }
+
+
+
+
+ private static String QuoteString(final String sText)
+ {
+ return "\"" + sText.replace("\"", "&quot;").replace(" ", "%20") + "\"";
+ }
+
+
+
+
+ private final FiniteAutomatonContainer maAutomatons;
+ private final SimpleTypeContainer maSimpleTypes;
+ private final NamespaceMap maNamespaces;
+ private final Map<String,Integer> maNameToIdMap;
+ private final Map<String,Integer> maPrefixToIdMap;
+ private final Map<String,Integer> maTypeNameToIdMap;
+ private final Map<String,Integer> maAttributeValueToIdMap;
+}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/HtmlGenerator.java b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/HtmlGenerator.java
new file mode 100644
index 000000000000..189554766ada
--- /dev/null
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/HtmlGenerator.java
@@ -0,0 +1,623 @@
+/**************************************************************
+*
+* 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.generator.html;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+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.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.Schema;
+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 single HTML page that shows information about all
+ * complex and simple types.
+ */
+public class HtmlGenerator
+ implements INodeVisitor
+{
+ public HtmlGenerator(
+ final SchemaBase aSchemaBase,
+ final Map<String, Schema> aTopLevelSchemas,
+ final File aOutputFile)
+ {
+ maSchemaBase = aSchemaBase;
+ maTopLevelSchemas = aTopLevelSchemas;
+ msIndentation = "";
+ msSingleIndentation = " ";
+ msSpace = " ";
+ try
+ {
+ maOut = new PrintStream(new FileOutputStream(aOutputFile));
+ } catch (FileNotFoundException aException)
+ {
+ aException.printStackTrace();
+ throw new RuntimeException(aException);
+ }
+ }
+
+
+
+
+ /** Read a template HTML file, expand its $... references and write the resulting content.
+ */
+ public void Generate ()
+ {
+ CopyFile("linking-template.html", true);
+ maOut.close();
+ }
+
+
+
+
+ private void CopyFile (
+ final String sBasename,
+ final boolean bIsTemplate)
+ {
+ try
+ {
+ final BufferedReader aIn = new BufferedReader(
+ new InputStreamReader(
+ new FileInputStream(
+ new File(
+ new File("bin/org/apache/openoffice/ooxml/schema/generator/html"),
+ sBasename))));
+
+ final Pattern aReferencePattern = Pattern.compile("^(.*?)\\$([^\\$]+)\\$(.*)$");
+ while (true)
+ {
+ final String sLine = aIn.readLine();
+ if (sLine == null)
+ break;
+
+ if (bIsTemplate)
+ {
+ final Matcher aMatcher = aReferencePattern.matcher(sLine);
+ if (aMatcher.matches())
+ {
+ maOut.println(aMatcher.group(1));
+ switch(aMatcher.group(2))
+ {
+ case "CSS":
+ CopyFile("display.css", false);
+ break;
+ case "CODE":
+ CopyFile("code.js", false);
+ break;
+ case "DATA":
+ WriteJsonData();
+ break;
+ }
+ maOut.printf("%s\n", aMatcher.group(3));
+ }
+ else
+ maOut.printf("%s\n", sLine);
+ }
+ else
+ maOut.printf("%s\n", sLine);
+ }
+ aIn.close();
+ }
+ catch (final Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+
+
+
+ private void WriteJsonData ()
+ {
+ maOut.printf("Data={\n");
+
+ WriteTopLevelNodes(maSchemaBase.ComplexTypes.GetSorted());
+ WriteTopLevelNodes(maSchemaBase.SimpleTypes.GetSorted());
+ WriteTopLevelNodes(maSchemaBase.Groups.GetSorted());
+ WriteTopLevelNodes(maSchemaBase.AttributeGroups.GetSorted());
+
+ maOut.printf("}\n");
+ }
+
+
+
+
+ private void WriteTopLevelNodes (final Iterable<? extends INode> aNodes)
+ {
+ for (final INode aNode : aNodes)
+ {
+ maOut.printf(" \"%s\" : {\n", aNode.GetName().GetDisplayName());
+
+ final String sSavedIndentation = msIndentation;
+ msIndentation += msSingleIndentation + msSingleIndentation;
+ aNode.AcceptVisitor(this);
+ msIndentation = sSavedIndentation;
+
+ maOut.printf(" }, \n");
+ }
+ }
+
+
+
+
+ @Override
+ public void Visit (final All aNode)
+ {
+ WritePair("type", "all");
+ WriteLocation(aNode);
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Any aNode)
+ {
+ WritePair("type", "any");
+ WriteLocation(aNode);
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final ComplexContent aNode)
+ {
+ WritePair("type", "complex-content");
+ WriteLocation(aNode);
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final ComplexType aNode)
+ {
+ WritePair("type", "complex-type");
+ WritePair("name", aNode.GetName().GetDisplayName());
+ WriteLocation(aNode);
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final ComplexTypeReference aReference)
+ {
+ WritePair("type", "complex-type-reference");
+ WriteLocation(aReference);
+ WritePair("referenced-complex-type", aReference.GetReferencedTypeName().GetDisplayName());
+ WriteAttributes(aReference);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Choice aNode)
+ {
+ WritePair("type", "choice");
+ WriteLocation(aNode);
+ WriteChildren(aNode);
+ WriteAttributes(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Element aNode)
+ {
+ WritePair("type", "element");
+ WriteLocation(aNode);
+ WritePair("tag", aNode.GetElementName().GetDisplayName());
+ WritePair("result-type", aNode.GetTypeName().GetDisplayName());
+ WriteAttributes(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final ElementReference aReference)
+ {
+ WritePair("type", "element-type-reference");
+ WriteLocation(aReference);
+ WritePair("referenced-element", aReference.GetReferencedElementName().GetDisplayName());
+ WriteAttributes(aReference);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Extension aNode)
+ {
+ WritePair("type", "extension");
+ WriteLocation(aNode);
+ WritePair("base-type", aNode.GetBaseTypeName().GetDisplayName());
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Group aNode)
+ {
+ WritePair("type", "group");
+ WriteLocation(aNode);
+ WritePair("name", aNode.GetName().GetDisplayName());
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final GroupReference aReference)
+ {
+ WritePair("type", "group-reference");
+ WriteLocation(aReference);
+ WritePair("referenced-group", aReference.GetReferencedGroupName().GetDisplayName());
+ WriteAttributes(aReference);
+ }
+
+
+
+
+ @Override
+ public void Visit (final OccurrenceIndicator aNode)
+ {
+ WritePair("type", "occurrence");
+ WriteLocation(aNode);
+ WritePair("minimum", aNode.GetDisplayMinimum());
+ WritePair("maximum", aNode.GetDisplayMaximum());
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Sequence aNode)
+ {
+ WritePair("type", "sequence");
+ WriteLocation(aNode);
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final BuiltIn aNode)
+ {
+ WritePair("type", "builtin");
+ WriteLocation(aNode);
+ WritePair("builtin-type", aNode.GetBuiltInType().GetQualifiedName().GetDisplayName());
+ WriteAttributes(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final List aNode)
+ {
+ WritePair("type", "list");
+ WriteLocation(aNode);
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Restriction aNode)
+ {
+ WritePair("type", "restriction");
+ WriteLocation(aNode);
+ WritePair("base-type", aNode.GetBaseType().GetDisplayName());
+ WriteAttributes(aNode);
+
+ if (aNode.HasFeature(Restriction.EnumerationBit))
+ WritePair("enumeration", Join(aNode.GetEnumeration(), ";"));
+ if (aNode.HasFeature(Restriction.PatternBit))
+ WritePair("pattern", QuoteString(aNode.GetPattern()));
+ if (aNode.HasFeature(Restriction.MinExclusiveBit))
+ WritePair("exclusive-minimum", aNode.GetMinExclusive());
+ if (aNode.HasFeature(Restriction.MinInclusiveBit))
+ WritePair("inclusive-minimum", aNode.GetMinInclusive());
+ if (aNode.HasFeature(Restriction.MaxInclusiveBit))
+ WritePair("inclusive-maximum", aNode.GetMaxInclusive());
+ if (aNode.HasFeature(Restriction.MaxInclusiveBit))
+ WritePair("inclusive-maximum", aNode.GetMaxInclusive());
+ if (aNode.HasFeature(Restriction.LengthBit))
+ WritePair("length", Integer.toString(aNode.GetLength()));
+ if (aNode.HasFeature(Restriction.MinLengthBit))
+ WritePair("minimum-length", Integer.toString(aNode.GetMinimumLength()));
+ if (aNode.HasFeature(Restriction.MaxLengthBit))
+ WritePair("maximum-length", Integer.toString(aNode.GetMaximumLength()));
+ assert(aNode.GetChildCount() == 0);
+ }
+
+
+
+
+ @Override
+ public void Visit (final SimpleContent aNode)
+ {
+ WritePair("type", "simple-content");
+ WriteLocation(aNode);
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final SimpleType aNode)
+ {
+ WritePair("type", "simple-type");
+ WriteLocation(aNode);
+ WritePair("name", aNode.GetName().GetDisplayName());
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final SimpleTypeReference aReference)
+ {
+ WritePair("type", "simple-type-reference");
+ WriteLocation(aReference);
+ WritePair("referenced-simple-type", aReference.GetReferencedTypeName().GetDisplayName());
+ WriteAttributes(aReference);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Union aNode)
+ {
+ WritePair("type", "union");
+ WriteLocation(aNode);
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final AttributeGroup aNode)
+ {
+ WritePair("type", "attribute-group");
+ WriteLocation(aNode);
+ WritePair("name", aNode.GetName().GetDisplayName());
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final AttributeReference aReference)
+ {
+ WritePair("type", "attribute-reference");
+ WriteLocation(aReference);
+ WritePair("referenced-attribute", aReference.GetReferencedName().GetDisplayName());
+ WriteAttributes(aReference);
+ }
+
+
+
+
+ @Override
+ public void Visit (final Attribute aNode)
+ {
+ WritePair("type", "attribute");
+ WriteLocation(aNode);
+ WritePair("name", aNode.GetName().GetDisplayName());
+ WritePair("default-value", aNode.GetDefault());
+ WritePair("value-type", aNode.GetTypeName().GetDisplayName());
+ WritePair("use", aNode.GetUse().toString());
+ WriteAttributes(aNode);
+ WriteChildren(aNode);
+ }
+
+
+
+
+ @Override
+ public void Visit (final AttributeGroupReference aReference)
+ {
+ WritePair("type", "attribute-group-reference");
+ WriteLocation(aReference);
+ WritePair("referenced-attribute-group", aReference.GetReferencedName().GetDisplayName());
+ WriteAttributes(aReference);
+ }
+
+
+
+
+ private void WriteChildren (
+ final INode aParent)
+ {
+ if (aParent.GetChildCount() > 0)
+ {
+ maOut.printf("%s\"children\" : [\n", msIndentation);
+ int nIndex = 0;
+ for (final INode aChild : aParent.GetChildren())
+ {
+ maOut.printf("%s%s{\n", msIndentation, msSingleIndentation, nIndex++);
+
+ final String sSavedIndentation = msIndentation;
+ msIndentation += msSingleIndentation + msSingleIndentation;
+ aChild.AcceptVisitor(this);
+ msIndentation = sSavedIndentation;
+
+ maOut.printf("%s%s},\n", msIndentation, msSingleIndentation);
+ }
+
+ maOut.printf("%s]\n", msIndentation);
+ }
+ }
+
+
+
+
+ private void WriteAttributes (
+ final INode aParent)
+ {
+ if (aParent.GetAttributeCount() > 0)
+ {
+ maOut.printf("%s\"attributes\" : [\n", msIndentation);
+ int nIndex = 0;
+ for (final INode aAttribute: aParent.GetAttributes())
+ {
+
+ maOut.printf("%s%s{\n", msIndentation, msSingleIndentation, nIndex++);
+
+ final String sSavedIndentation = msIndentation;
+ msIndentation += msSingleIndentation + msSingleIndentation;
+ aAttribute.AcceptVisitor(this);
+ msIndentation = sSavedIndentation;
+
+ maOut.printf("%s%s},\n", msIndentation, msSingleIndentation);
+ }
+
+ maOut.printf("%s],\n", msIndentation);
+ }
+ }
+
+
+
+
+ private void WriteLocation (
+ final INode aNode)
+ {
+ if (aNode.GetLocation() == null)
+ return;
+
+ WritePair("location", aNode.GetLocation().toString());
+ }
+
+
+
+
+ private void WritePair (
+ final String sKey,
+ final String sValue)
+ {
+ maOut.printf("%s\"%s\"%s:%s\"%s\"%s\n", msIndentation, sKey, msSpace, msSpace, sValue, ",");
+ }
+
+
+
+
+ private String Join (final Collection<String> aValues, final String sSeparator)
+ {
+ final Iterator<String> aIterator = aValues.iterator();
+ if ( ! aIterator.hasNext())
+ return "";
+
+ final StringBuffer aBuffer = new StringBuffer(aIterator.next());
+ while (aIterator.hasNext())
+ {
+ aBuffer.append(sSeparator);
+ aBuffer.append(aIterator.next());
+ }
+ return aBuffer.toString();
+ }
+
+
+
+
+ private String QuoteString (final String sValue)
+ {
+ return sValue.replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;");
+ }
+
+
+
+
+ private final SchemaBase maSchemaBase;
+ private final Map<String, Schema> maTopLevelSchemas;
+ private final PrintStream maOut;
+ private String msIndentation;
+ private final String msSingleIndentation;
+ private final String msSpace;
+}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/code.js b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/code.js
new file mode 100644
index 000000000000..64be9682e913
--- /dev/null
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/code.js
@@ -0,0 +1,442 @@
+function LoadData ()
+{
+ gTypeNames = [];
+ ComplexTypeNames = [];
+ SimpleTypeNames = [];
+ for (var sName in Data)
+ {
+ gTypeNames.push(sName);
+ switch(Data[sName].type)
+ {
+ case "complex-type":
+ ComplexTypeNames.push(sName);
+ break;
+
+ case "simple-type":
+ SimpleTypeNames.push(sName);
+ break;
+ }
+ }
+ document.getElementById("message").innerHTML = "there are " + ComplexTypeNames.length + " complex types and "
+ + SimpleTypeNames.length +" simple types";
+}
+
+
+
+
+function InitializeSearch ()
+{
+ CurrentTypeName = "";
+ TypeHistory = Array();
+ LoadData();
+ ShowType("A:ST_Overlap");
+}
+
+
+
+
+function CheckInput (aField, aEvent)
+{
+ switch(aEvent.keyCode)
+ {
+ case 38:
+ --selection_index;
+ if (selection_index < 0)
+ selection_index = matches.length-1;
+ break;
+ case 40:
+ ++selection_index;
+ if (selection_index >= matches.length)
+ selection_index = 0;
+ break;
+ default:
+ matches = GetMatches(aField.value);
+ selection_index = 0;
+ }
+
+ ShowMatches(matches, selection_index);
+}
+
+
+
+
+function GetMatches (sPattern)
+{
+ var aLcPatterns = sPattern.toLowerCase().split(/\s+/);
+
+ var nTypeCount = gTypeNames.length;
+
+ var aMatches = [];
+ for (index=0; index<nTypeCount; ++index)
+ {
+ var sTypeName = gTypeNames[index];
+ var aParts = new Array(sTypeName);
+ var sLcTypeName = sTypeName.toLowerCase();
+ var bIsMatch = true;
+ var nSearchStart = 0;
+ for (nPatternIndex=0; nPatternIndex<aLcPatterns.length && bIsMatch; ++nPatternIndex)
+ {
+ var sPattern = aLcPatterns[nPatternIndex];
+ var nMatchStart = sLcTypeName.indexOf(sPattern, nSearchStart);
+ if (nMatchStart >= 0)
+ {
+ var nMatchEnd = nMatchStart + sPattern.length;
+ aParts.push(sTypeName.substring(nSearchStart, nMatchStart));
+ aParts.push(sTypeName.substring(nMatchStart, nMatchEnd));
+ nSearchStart = nMatchEnd;
+ }
+ else
+ {
+ // Only some patterns are matched.
+ bIsMatch = false;
+ }
+ }
+ if (bIsMatch)
+ {
+ if (nMatchEnd < sTypeName.length-1)
+ aParts.push(sTypeName.substring(nMatchEnd));
+ aMatches.push(aParts);
+ }
+ }
+ return aMatches;
+}
+
+
+
+
+/** Show the matching types.
+ * As there can be a great many matching types, some sort of abbreviation is necessary.
+ * Format all matches into lines of n entries.
+ * Show the line containing the selected match and the ones before and after.
+ * Show also the number of ommited matches.
+ */
+function ShowMatches (aMatches, nSelectionIndex)
+{
+ var sText = "";
+
+ var nHalfRange = 10;
+ var nMatchesPerLine = 5;
+ var nLineCount = Math.floor((aMatches.length+nMatchesPerLine-1) / nMatchesPerLine);
+ var nLineOfSelection = Math.floor(nSelectionIndex / nMatchesPerLine);
+ var nFirstDisplayedLine = nLineOfSelection>0 ? nLineOfSelection-1 : 0;
+ var nLastDisplayedLine = nLineOfSelection<nLineCount-1 ? nLineOfSelection+1 : nLineCount-1;
+
+ for (nLineIndex=nFirstDisplayedLine; nLineIndex<=nLastDisplayedLine; ++nLineIndex)
+ {
+ var nLineStartIndex = nLineIndex * nMatchesPerLine;
+ var nLineEndIndex = nLineStartIndex + nMatchesPerLine - 1;
+ if (nLineEndIndex >= aMatches.length)
+ nLineEndIndex = aMatches.length-1;
+
+ sText += "<tr>"
+ for (nIndex=nLineStartIndex; nIndex<=nLineEndIndex; ++nIndex)
+ {
+ var aMatch = aMatches[nIndex];
+ var sTypeName = aMatch[0];
+ var sMatch = "";
+ for (nPartIndex=1; nPartIndex<aMatch.length; ++nPartIndex)
+ {
+ if ((nPartIndex%2)==0)
+ sMatch += "<span class=\"match-highlight\">"+aMatch[nPartIndex]+"</span>";
+ else
+ sMatch += aMatch[nPartIndex];
+ }
+ sText += "<td>"
+ if (nIndex == nSelectionIndex)
+ {
+ sText += " <span class=\"typelink current-match\">" + sMatch + "</span>";
+ }
+ else
+ {
+ sText += " " + GetTypeLink(sMatch, sTypeName, -1);
+ }
+ sText += "</td>"
+ }
+
+ sText += "</tr>";
+ }
+ if (nFirstDisplayedLine > 0)
+ sText = "<tr><td>["+(nFirstDisplayedLine*nMatchesPerLine)+" matches] ...</td><tr>" + sText;
+ if (nLastDisplayedLine+1 < nLineCount)
+ sText += "<tr><td>... ["+((nLineCount-nLastDisplayedLine-1)*nMatchesPerLine)+" matches]</td></tr>";
+
+ document.getElementById('matches').innerHTML = "<table>"+sText+"</table>";
+ if (aMatches.length == 0)
+ {
+ document.getElementById('match-count').innerHTML = "no match:";
+ }
+ else
+ {
+ if (aMatches.length == 1)
+ document.getElementById('match-count').innerHTML = "single match:";
+ else
+ document.getElementById('match-count').innerHTML = aMatches.length+" matches:";
+
+ ShowType(aMatches[nSelectionIndex][0]);
+ }
+}
+
+
+
+
+function GetTopLevelNodeForTypeName(sTypeName)
+{
+ if (sTypeName in Data)
+ return Data[sTypeName];
+ else
+ alert(sTypeName +" is not a known complex type, simple type, or group");
+}
+
+
+
+
+/** Show the specified type.
+ * When nHistoryIndex is not -1 then the history is shortened to that (before that) index.
+ */
+function ShowType (sTypeName, nHistoryIndex)
+{
+ if (nHistoryIndex == -1)
+ {
+ if (CurrentTypeName != "")
+ {
+ TypeHistory.push(CurrentTypeName);
+ ShowHistory();
+ }
+ }
+ else
+ {
+ TypeHistory = TypeHistory.slice(0,nHistoryIndex);
+ ShowHistory();
+ }
+ CurrentTypeName = sTypeName;
+
+ var aElement = document.getElementById('result');
+
+ // Remove the old content.
+ while(aElement.childNodes.length > 0)
+ aElement.removeChild(aElement.firstChild);
+
+ // Create the new content.
+ var list = CreateDomTreeForType(GetTopLevelNodeForTypeName(sTypeName), "ul");
+
+ // Show the new content.
+ aElement.appendChild(list);
+}
+
+
+
+
+/** Create a dom sub tree for the given OOXML type that is ready for insertion into the global DOM tree.
+ */
+function CreateDomTreeForType (aNode, sType)
+{
+ var aEntry = document.createElement(sType);
+
+ if (typeof aNode==='undefined')
+ {
+ aEntry.innerHTML = "undefined node";
+ }
+ else if (typeof aNode.type==='undefined')
+ {
+ aEntry.innerHTML = "unknown type";
+ }
+ else
+ {
+ switch(aNode.type)
+ {
+ case "attribute":
+ aEntry.innerHTML = CreateValueTable([
+ "attribute",
+ "type:", GetTypeLink(aNode["value-type"], aNode["value-type"], -1),
+ "use:", aNode.use]);
+ break;
+
+ case "attribute-reference":
+ aEntry.innerHTML = CreateReference(aNode["referenced-attribute"]);
+ break;
+
+ case "builtin":
+ aEntry.innerHTML = CreateValueTable(
+ ["builtin",
+ "name:", aNode['builtin-type']
+ ]);
+ break;
+
+ case "complex-type":
+ aEntry.innerHTML = aNode.type + " " + aNode.name;
+ break;
+
+ case "complex-type-reference":
+ aEntry.innerHTML = CreateReference(aNode["referenced-complex-type"]);
+ break;
+
+ case "group":
+ aEntry.innerHTML = aNode.type + " " + aNode.name;
+ break;
+
+ case "group-reference":
+ aEntry.innerHTML = CreateReference("group", aNode["referenced-group"]);
+ break;
+
+ case "element":
+ aEntry.innerHTML = "element <b>" + aNode["tag"] + "</b> -> " + GetTypeLink(aNode["result-type"], aNode["result-type"], -1);
+ break;
+
+ case "occurrence":
+ aEntry.innerHTML = aNode.minimum +" -> " + aNode.maximum;
+ break;
+
+ case "restriction":
+ aEntry.innerHTML = CreateRestrictionRepresentation(aNode);
+ break;
+
+ case "sequence":
+ aEntry.innerHTML = "sequence";
+ break;
+
+ case "simple-type":
+ aEntry.innerHTML = aNode.type + " " + aNode.name;
+ break;
+
+ case "simple-type-reference":
+ aEntry.innerHTML = CreateReference("simple-type", aNode["referenced-simple-type"]);
+ break;
+
+ default:
+ aEntry.innerHTML = aNode.type;
+ break;
+ }
+
+ // Add nodes for attributes.
+ var aAttributes= aNode["attributes"];
+ if ( ! (typeof aAttributes==='undefined' || aAttributes.length == 0))
+ {
+ var aAttributeList = document.createElement("ul");
+ aEntry.appendChild(aAttributeList);
+
+ for (var nIndex=0; nIndex<aAttributes.length; ++nIndex)
+ {
+ var aAttributeEntry = CreateDomTreeForType(aAttributes[nIndex], "li");
+ aAttributeList.appendChild(aAttributeEntry);
+ }
+ }
+
+ // Add nodes for children.
+ var aChildren = aNode["children"];
+ if ( ! (typeof aChildren==='undefined' || aChildren.length == 0))
+ {
+ var aChildrenList = document.createElement("ul");
+ aEntry.appendChild(aChildrenList);
+
+ for (var nIndex=0; nIndex<aChildren.length; ++nIndex)
+ {
+ var aChildrenEntry = CreateDomTreeForType(aChildren[nIndex], "li");
+ aChildrenList.appendChild(aChildrenEntry);
+ }
+ }
+ }
+ return aEntry;
+}
+
+
+
+
+function GetTypeLink (sText, sTarget, nIndex)
+{
+ return "<span class=\"typelink\" id=\""+sTarget+"\" onclick=\"ShowType('"+sTarget+"',"+nIndex+")\">"+sText+"</span>";
+}
+
+
+
+
+function CreateValueTable (aValues)
+{
+ var sResult = "<table class=\"value-table\"><tr><td>"+aValues[0]+"</td><td>"+aValues[1]+"</td><td>"+aValues[2]+"</td></tr>";
+ for (nIndex=3; nIndex<aValues.length; nIndex+=2)
+ {
+ sResult += "<tr><td></td><td>"+aValues[nIndex]+"</td><td>"+aValues[nIndex+1]+"</td></tr>";
+ }
+ sResult += "</table>";
+ return sResult;
+}
+
+
+
+
+function CreateReference (sWhat, sTypeName)
+{
+ return "reference to "+sWhat+" "+GetTypeLink(sTypeName, sTypeName, -1) + " "
+ +CreateButton(
+ sTypeName,
+ "show",
+ "ToggleTypeReferenceExpansion('"+sTypeName+"')")
+ +"<br><span id=\"expansion-"+sTypeName+"\"></span>";
+}
+
+
+
+
+function CreateButton (sId, sText, sExpandAction)
+{
+ return "<span class=\"button\" id=\"button-"+sId+"\" onClick=\""+sExpandAction+"\">"+sText+"</span>";
+}
+
+
+
+
+function ToggleTypeReferenceExpansion(sTypeName)
+{
+ var aButton = document.getElementById("button-"+sTypeName);
+ var aExpansion = document.getElementById("expansion-"+sTypeName);
+ if (aButton.innerHTML == "show")
+ {
+ aExpansion.appendChild(CreateDomTreeForType(Data[sTypeName], "span"));
+ aButton.innerHTML = "hide";
+ }
+ else
+ {
+ aExpansion.innerHTML = "";
+ aButton.innerHTML = "show";
+ }
+}
+
+
+
+
+function ShowHistory ()
+{
+ var aElement = document.getElementById('history');
+ var sContent = "History:";
+ for (nIndex=0; nIndex<TypeHistory.length; ++nIndex)
+ {
+ if (nIndex == 0)
+ sContent += " ";
+ else
+ sContent += ", ";
+ sContent += GetTypeLink(TypeHistory[nIndex], TypeHistory[nIndex], nIndex);
+ }
+ aElement.innerHTML = sContent;
+}
+
+
+
+
+function CreateRestrictionRepresentation (aNode)
+{
+ var aTableData = ["restriction", "based on:", GetTypeLink(aNode['base-type'], aNode['base-type'], -1)];
+ AddValue(aNode, "enumeration", aTableData);
+ AddValue(aNode, "pattern", aTableData);
+ AddValue(aNode, "length", aTableData);
+ return CreateValueTable(aTableData);
+}
+
+
+
+function AddValue (aMap, sKey, aTableData)
+{
+ if (sKey in aMap)
+ {
+ aTableData.push(sKey+":");
+ aTableData.push(aMap[sKey]);
+ }
+}
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/display.css b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/display.css
new file mode 100644
index 000000000000..d7d267e9ed9d
--- /dev/null
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/display.css
@@ -0,0 +1,57 @@
+* {
+ font-family: Arial;
+ font-style:normal;
+ }
+.typelink {
+ cursor: pointer; cursor: hand;
+ color: #688;
+ }
+.typelink:link { color:#003; background-color:transparent; }
+.typelink:visited { color:#003; background-color:transparent; }
+.typelink:hover {
+ text-decoration: underline;
+ }
+.typelink:active { color:#003; background-color:#acc; }
+
+.value-table { display: inline-table; }
+
+
+.button {
+ box-shadow:inset 0px 1px 0px 0px #ffffff;
+ background-color:#ededed;
+ border-top-left-radius:4px;
+ border-top-right-radius:4px;
+ border-bottom-right-radius:4px;
+ border-bottom-left-radius:4px;
+ border:1px solid #dcdcdc;
+ display: inline-block;
+ color: #777777;
+ font-size: 15px;
+ font-weight: bold;
+ height: 20px;
+ line-height: 20px;
+ width: 80px;
+ text-align:center;
+ vertical-align: middle;
+ text-shadow:1px 1px 0px #ffffff;
+ cursor: pointer; cursor: hand;
+ }
+
+.button:hover {
+ background-color:#dfdfdf;
+ }
+
+.button:active {
+ position: relative;
+ top: 1px;
+ background-color:#c0c0c0;
+ }
+
+.current-match {
+ font-weight: bold;
+ background-color:#c0c0c0;
+ }
+
+.match-highlight {
+ color: #ff0000;
+ }
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/linking-template.html b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/linking-template.html
new file mode 100644
index 000000000000..c20c67c57165
--- /dev/null
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/linking-template.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8" />
+ <link rel="stylesheet" type="text/css" href="C:\source\ooxml\git\main\ooxml\source\framework\SchemaParser\src\org\apache\openoffice\ooxml\schema\generator\html\display.css">
+ </link>
+ <script type="text/javascript">
+ $DATA$
+ </script>
+ <script type="text/javascript" src="C:\source\ooxml\git\main\ooxml\source\framework\SchemaParser\src\org\apache\openoffice\ooxml\schema\generator\html\code.js">
+ </script>
+ </head>
+ <body onLoad="InitializeSearch()">
+ <div id="message"></div>
+ <input onKeyUp="CheckInput(this,event)"></input>
+ <div id="history"></div>
+ <br><br><div id="match-count">Matches:</div><br>
+ <div id="matches" cols="100" rows="20" defaultValue="type text to see matching types"></div>
+ <br>
+ <div id="result">no result yet</div>
+ </body>
+</html>
diff --git a/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/template.html b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/template.html
new file mode 100644
index 000000000000..2c174c137717
--- /dev/null
+++ b/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/generator/html/template.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8" />
+ <style type="text/css">
+ $CSS$
+ </style>
+ <script type="text/javascript">
+ $DATA$
+ </script>
+ <script type="text/javascript">
+ $CODE$
+ </script>
+ </head>
+ <body onLoad="InitializeSearch()">
+ <div id="message"></div>
+ <input onKeyUp="CheckInput(this,event)"></input>
+ <br><br><div id="match-count">Matches:</div><br>
+ <div id="history"></div>
+ <div id="matches" cols="100" rows="20" defaultValue="type text to see matching types"></div>
+ <br>
+ <div id="result">no result yet</div>
+ </body>
+</html>