diff options
Diffstat (limited to 'ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/attribute/AttributeManager.java')
-rw-r--r-- | ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/attribute/AttributeManager.java | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/attribute/AttributeManager.java b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/attribute/AttributeManager.java new file mode 100644 index 000000000000..55b1df9f1f5e --- /dev/null +++ b/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/attribute/AttributeManager.java @@ -0,0 +1,273 @@ +/************************************************************** +* +* 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.parser.attribute; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import org.apache.openoffice.ooxml.parser.Log; +import org.apache.openoffice.ooxml.parser.NameMap; +import org.apache.openoffice.ooxml.parser.NamespaceMap; +import org.apache.openoffice.ooxml.parser.type.SimpleTypeManager; + + +/** Match a set of attributes from the document with the attribute + * specifications of a state. + * + */ +public class AttributeManager +{ + /** 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, + final NameMap aStateNameMap, + final SimpleTypeManager aSimpleTypeManager, + final Vector<String> aErrorsAndWarnings) + { + maStateIdToAttributesMap = new HashMap<>(); + maNamespaceMap = aNamespaceMap; + maNameMap = aNameMap; + maStateNameMap = aStateNameMap; + maSimpleTypeManager = aSimpleTypeManager; + maErrorsAndWarnings = aErrorsAndWarnings; + ParseData(aData); + } + + + + + private void ParseData (final Vector<String[]> aData) + { + 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 int nAttributeTypeId = aLine[5].equals("null") ? -1 : Integer.parseInt(aLine[5]); + final boolean bIsOptional = aLine[6].startsWith("o"); + final String sDefault = aLine[7]; + // State name. + final String sAttributeName = aLine[9]; + // Attribute type name. + + 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, + nAttributeTypeId); + + 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 AttributeValues ParseAttributes ( + final int nStateId, + final AttributeProvider aDocumentAttributes) + { + final AttributeValues aValues = new AttributeValues(); + + final Map<Integer,AttributeDescriptor> aAttributesPerState = maStateIdToAttributesMap.get(nStateId); + if (aAttributesPerState == null) + { + 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 + { + final Set<AttributeDescriptor> aUsedAttributes = new HashSet<>(); + + // Process all attributes from the document. + for (final String[] aEntry : aDocumentAttributes) + { + final String sRawValue = aEntry[2]; + final AttributeDescriptor aAttributeDescriptor = ProcessAttribute( + aEntry[0], + aEntry[1], + sRawValue, + aAttributesPerState); + aUsedAttributes.add(aAttributeDescriptor); + final Object aProcessedValue = maSimpleTypeManager.PreprocessValue( + sRawValue, + aAttributeDescriptor); + if (aProcessedValue == null) + { + maSimpleTypeManager.PreprocessValue( + sRawValue, + aAttributeDescriptor); + throw new RuntimeException( + String.format("value '%s' of attribute '%s' is not recognized", + sRawValue, + aAttributeDescriptor.GetName())); + } + aValues.AddAttribute( + aAttributeDescriptor, + sRawValue, + aProcessedValue); + + 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 %s(%d) and value %s('%s')\n", + maNamespaceMap.GetDescriptorForId(aAttributeDescriptor.GetNamespaceId()).Prefix, + maNameMap.GetNameForId(aAttributeDescriptor.GetNameId()), + aAttributeDescriptor.GetNamespaceId(), + aAttributeDescriptor.GetNameId(), + maStateNameMap.GetNameForId(aAttributeDescriptor.GetTypeId()), + aAttributeDescriptor.GetTypeId(), + aProcessedValue, + sRawValue); + } + } + + // Check if all required attributes where given. + for (final AttributeDescriptor aAttribute : aAttributesPerState.values()) + { + if ( ! aUsedAttributes.contains(aAttribute)) + { + if ( ! aAttribute.IsOptional()) + { + final String sMessage = String.format("attribute '"+aAttribute.GetName()+"' is not present but also not optional"); + if (maErrorsAndWarnings != null) + maErrorsAndWarnings.add(sMessage); + else + throw new RuntimeException(sMessage); + } + else + { + // Add an entry that gives access to the default value. + aValues.AddAttribute(aAttribute, null, null); + } + } + } + } + + return aValues; + } + + + + + 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); + } + } + + + + + public int GetAttributeCount () + { + int nCount = 0; + for (final Map<Integer,AttributeDescriptor> aMap : maStateIdToAttributesMap.values()) + nCount += aMap.size(); + return nCount; + } + + + + + private final Map<Integer,Map<Integer,AttributeDescriptor>> maStateIdToAttributesMap; + private final NamespaceMap maNamespaceMap; + private final NameMap maNameMap; + private final NameMap maStateNameMap; + private final SimpleTypeManager maSimpleTypeManager; + private final Vector<String> maErrorsAndWarnings; +} |