summaryrefslogtreecommitdiff
path: root/ooxml/source/framework/JavaPartManager/src
diff options
context:
space:
mode:
Diffstat (limited to 'ooxml/source/framework/JavaPartManager/src')
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/ContentType.java77
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/ContentTypes.java150
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/IReferenceProvider.java6
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/OOXMLPackage.java56
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/Package.java158
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/Part.java89
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartManager.java145
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartManagerPrototype.java33
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartName.java130
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/RelatedParts.java131
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/RelationshipType.java112
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/ContentTypesParser.java30
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/ParserFactory.java46
-rw-r--r--ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/RelationshipParser.java30
14 files changed, 1193 insertions, 0 deletions
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/ContentType.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/ContentType.java
new file mode 100644
index 000000000000..fc147cbd5cd4
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/ContentType.java
@@ -0,0 +1,77 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+public enum ContentType
+{
+ ApplicationDrawing ("application/vnd.openxmlformats-officedocument.vmlDrawing"),
+ ApplicationExcel ("application/vnd.ms-excel"),
+ ApplicationXML ("application/xml"),
+ Chart ("application/vnd.openxmlformats-officedocument.drawingml.chart+xml"),
+ ContentTypes (""),
+ CoreProperties ("application/vnd.openxmlformats-package.core-properties+xml"),
+ CustomXMLProperties ("application/vnd.openxmlformats-officedocument.customXmlProperties+xml"),
+ ExtendedProperties ("application/vnd.openxmlformats-officedocument.extended-properties+xml"),
+ ImageGIF ("image/gif"),
+ ImageJPG ("image/png"),
+ ImagePNG ("image/jpeg"),
+ OleObject ("application/vnd.openxmlformats-officedocument.oleObject"),
+ PmlDocument ("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"),
+ PmlHandoutMaster ("application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml"),
+ PmlNotesMaster ("application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml"),
+ PmlNotesSlide ("application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml"),
+ PmlProperties ("application/vnd.openxmlformats-officedocument.presentationml.presProps+xml"),
+ PmlSlide ("application/vnd.openxmlformats-officedocument.presentationml.slide+xml"),
+ PmlSlideLayout ("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"),
+ PmlSlideMaster ("application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"),
+ PmlTableStyles ("application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"),
+ PmlViewProperties ("application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"),
+ Relationships ("application/vnd.openxmlformats-package.relationships+xml"),
+ SmlSheet ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
+ Theme ("application/vnd.openxmlformats-officedocument.theme+xml"),
+ ThemeOverride ("application/vnd.openxmlformats-officedocument.themeOverride+xml"),
+ Thumbnail ("http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"),
+ WmlDocument ("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"),
+ WmlEndNotes ("application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"),
+ WmlFontTable ("application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"),
+ WmlFootNotes ("application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"),
+ WmlFooter ("application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml"),
+ WmlHeader ("application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"),
+ WmlNumbering ("application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"),
+ WmlSettings ("application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"),
+ WmlStyles ("application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"),
+ WmlWebSettings ("application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"),
+
+ Unknown("");
+
+
+
+
+ ContentType (final String sMimeType)
+ {
+ msMimeType = sMimeType;
+ }
+
+
+
+
+ public static ContentType CreateForString (final String sContentType)
+ {
+ for (final ContentType eType : values())
+ if (eType.msMimeType.equals(sContentType))
+ return eType;
+ System.err.printf("content type '%s' is not known\n", sContentType);
+ return Unknown;
+ }
+
+
+
+
+ public String GetLongName ()
+ {
+ return msMimeType;
+ }
+
+
+
+
+ private final String msMimeType;
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/ContentTypes.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/ContentTypes.java
new file mode 100644
index 000000000000..d17a082106a8
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/ContentTypes.java
@@ -0,0 +1,150 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.stream.Location;
+
+import org.apache.openoffice.ooxml.framework.part.parser.ParserFactory;
+import org.apache.openoffice.ooxml.parser.ElementContext;
+import org.apache.openoffice.ooxml.parser.Parser;
+import org.apache.openoffice.ooxml.parser.action.ActionTrigger;
+import org.apache.openoffice.ooxml.parser.action.IAction;
+
+public class ContentTypes
+{
+ ContentTypes (final PartManager aPartManager)
+ {
+ maExtensionToContentTypeMap = new HashMap<>();
+ maPartNameToContentTypeMap = new HashMap<>();
+
+ // Technically the [Content_Types].xml stream is not a part and
+ // "[Content_Types].xml" is not a part name. But handling it like one
+ // makes the implementation a little bit easier and more readable.
+ final Part aContentTypesPart = new Part(
+ ContentType.ContentTypes,
+ aPartManager,
+ new PartName("/[Content_Types].xml"));
+
+ final Parser aParser = ParserFactory.getParser(
+ aContentTypesPart.getContentType(),
+ aContentTypesPart.getStream(),
+ null);
+ /*
+ DefineContext(
+ CT_Something,
+ int nValue,
+ CallbackObject aObject);
+
+ class CT_Something_Context : public Context
+ {
+ Context parent
+
+ attribute 1
+ ...
+ attribute n
+ int nValue;
+ CallbackObject aObject;
+ }
+
+ DefineElementStartAction(
+ CT_Something_Context,
+ aObject,
+ DoSomething);
+
+
+ case ElementStart of CT_Something:
+ maCurrentContext.aObject.DoSomething(maCurrentContext); // CT_Something_Context
+
+ //
+ CallbackObject.cxx
+
+ class CallbackObject
+ {
+ public: DoSomething(CT_Something_Context aContext)
+ {
+ aContext.attribute1
+ }
+ }
+
+ */
+ aParser.GetActionManager().AddElementStartAction(
+ ".*_CT_Default",
+ new IAction(){
+
+ @Override
+ public void Run(
+ final ActionTrigger eTrigger,
+ final ElementContext aContext,
+ final String sText,
+ final Location aStartLocation,
+ final Location aEndLocation)
+ {
+ ProcessDefault(
+ aContext.GetAttributes().GetRawAttributeValue("A_Extension"),
+ aContext.GetAttributes().GetRawAttributeValue("A_ContentType"));
+
+ }});
+ aParser.GetActionManager().AddElementStartAction(
+ ".*_CT_Override",
+ new IAction(){
+
+ @Override
+ public void Run(
+ final ActionTrigger eTrigger,
+ final ElementContext aContext,
+ final String sText,
+ final Location aStartLocation,
+ final Location aEndLocation)
+ {
+ ProcessOverride(
+ aContext.GetAttributes().GetRawAttributeValue("A_PartName"),
+ aContext.GetAttributes().GetRawAttributeValue("A_ContentType"));
+
+ }});
+
+
+ aParser.Parse();
+ }
+
+
+
+
+ public ContentType getTypeForPartName (final PartName aName)
+ {
+ ContentType eType = maPartNameToContentTypeMap.get(aName.GetFullname());
+ if (eType == null)
+ eType = maExtensionToContentTypeMap.get(aName.GetExtension());
+ if (eType == null)
+ eType = ContentType.Unknown;
+ return eType;
+ }
+
+
+
+
+ private void ProcessDefault (
+ final String sExtension,
+ final String sContentTypeName)
+ {
+ final ContentType eType = ContentType.CreateForString(sContentTypeName);
+ maExtensionToContentTypeMap.put(sExtension, eType);
+ }
+
+
+
+
+ private void ProcessOverride (
+ final String sPartName,
+ final String sContentTypeName)
+ {
+ final ContentType eType = ContentType.CreateForString(sContentTypeName);
+ maPartNameToContentTypeMap.put(sPartName, eType);
+ }
+
+
+
+
+ private final Map<String,ContentType> maExtensionToContentTypeMap;
+ private final Map<String,ContentType> maPartNameToContentTypeMap;
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/IReferenceProvider.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/IReferenceProvider.java
new file mode 100644
index 000000000000..9d47eb6f54fe
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/IReferenceProvider.java
@@ -0,0 +1,6 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+public interface IReferenceProvider
+{
+ RelatedParts getRelatedParts ();
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/OOXMLPackage.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/OOXMLPackage.java
new file mode 100644
index 000000000000..3e5310ada923
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/OOXMLPackage.java
@@ -0,0 +1,56 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+import java.io.File;
+import java.io.InputStream;
+
+public class OOXMLPackage
+ extends Package
+{
+ public static OOXMLPackage Create (final File aOOXMLFile)
+ {
+ return new OOXMLPackage(
+ aOOXMLFile.getAbsolutePath(),
+ new PartManager(aOOXMLFile));
+ }
+
+
+
+
+ private OOXMLPackage (final String sPath, final PartManager aPartManager)
+ {
+ super(sPath, aPartManager);
+ }
+
+
+
+
+ /** Return a list of stream names.
+ * Note that that list is not necessarily identical to the list of part
+ * names. It can contain entries that are not parts.
+ */
+ public String[] listStreamNames ()
+ {
+ return maPartManager.listStreamNames();
+ }
+
+
+
+
+ /** Return an InputStream object for the specified stream.
+ */
+ public InputStream getStream (final String sStreamName)
+ {
+ return maPartManager.getStreamForStreamName(sStreamName);
+ }
+
+
+
+
+ public Part getPart (final PartName aPartName)
+ {
+ return new Part (
+ maPartManager.getContentTypes().getTypeForPartName(aPartName),
+ maPartManager,
+ aPartName);
+ }
+} \ No newline at end of file
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/Package.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/Package.java
new file mode 100644
index 000000000000..dd31292cf135
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/Package.java
@@ -0,0 +1,158 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+import java.io.File;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+public class Package
+ implements IReferenceProvider
+{
+ public static Package Create (final File aOOXMLFile)
+ {
+ return new Package(
+ aOOXMLFile.getAbsolutePath(),
+ new PartManager(aOOXMLFile));
+ }
+
+
+
+
+ protected Package (
+ final String sFullFilename,
+ final PartManager aPartManager)
+ {
+ msFullFilename = sFullFilename;
+ maPartManager = aPartManager;
+ maRelatedParts = new RelatedParts(
+ new PartName(""),
+ aPartManager);
+
+ final PartName aDocumentPartName = maRelatedParts.GetSingleTargetForType(RelationshipType.OfficeDocument);
+ maOfficeDocumentPart = new Part(
+ maPartManager.getContentTypes().getTypeForPartName(aDocumentPartName),
+ maPartManager,
+ aDocumentPartName);
+ }
+
+
+
+
+ public Part getOfficeDocumentPart ()
+ {
+ return maOfficeDocumentPart;
+ }
+
+
+
+
+ public Iterable<Part> getDigitalSignaturesParts ()
+ {
+ // TODO
+ return new Vector<>();
+ }
+
+
+
+
+ public RelatedParts getRelatedParts ()
+ {
+ return maRelatedParts;
+ }
+
+
+
+
+ public boolean hasAppDefFilePropertiesPart ()
+ {
+ // TODO
+ return false;
+ }
+
+
+
+
+ public Part getAppDefFilePropertiesPart ()
+ {
+ // TODO
+ return null;
+ }
+
+
+
+
+ public boolean hasCoreFilePropertiesPart ()
+ {
+ // TODO
+ return false;
+ }
+
+
+
+
+ public Part getCoreFilePropertiesPart ()
+ {
+ // TODO
+ return null;
+ }
+
+
+
+
+ public boolean hasCustomFilePropertiesPart ()
+ {
+ // TODO
+ return false;
+ }
+
+
+
+
+ public Part getCustomFilePropertiesPart ()
+ {
+ // TODO
+ return null;
+ }
+
+
+
+
+ public String getFileName()
+ {
+ return msFullFilename;
+ }
+
+
+
+
+ /** Return a list of stream names.
+ * Note that that list is not necessarily identical to the list of part
+ * names. It can contain entries that are not parts.
+ */
+ public String[] listStreamNames ()
+ {
+ return maPartManager.listStreamNames();
+ }
+
+
+
+
+ /** Return an InputStream object for the specified stream.
+ */
+ public InputStream getStream (final String sStreamName)
+ {
+ return maPartManager.getStreamForStreamName(sStreamName);
+ }
+
+
+
+
+ private final String msFullFilename;
+ protected final PartManager maPartManager;
+ private final RelatedParts maRelatedParts;
+ private final Part maOfficeDocumentPart;
+} \ No newline at end of file
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/Part.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/Part.java
new file mode 100644
index 000000000000..28b2617a1494
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/Part.java
@@ -0,0 +1,89 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+import java.io.InputStream;
+
+public class Part
+ implements IReferenceProvider
+{
+ public Part (
+ final ContentType eType,
+ final PartManager aPartManager,
+ final PartName aPartName)
+ {
+ meContentType = eType;
+ maPartManager = aPartManager;
+ maPartName = aPartName;
+ maRelatedParts = null;
+ }
+
+
+
+
+ public Part getPartById (final String sId)
+ {
+ final PartName aName = getRelatedParts().GetTargetForId(sId);
+ return new Part(
+ maPartManager.getContentTypes().getTypeForPartName(aName),
+ maPartManager,
+ aName);
+ }
+
+
+
+
+ public Part getPartByRelationshipType (final RelationshipType eType)
+ {
+ final PartName aName = getRelatedParts().GetSingleTargetForType(eType);
+ return new Part(
+ maPartManager.getContentTypes().getTypeForPartName(aName),
+ maPartManager,
+ aName);
+ }
+
+
+
+
+ public PartName getPartName ()
+ {
+ return maPartName;
+ }
+
+
+
+
+ public ContentType getContentType ()
+ {
+ return meContentType;
+ }
+
+
+
+
+ public InputStream getStream()
+ {
+ return maPartManager.getStreamForPartName(maPartName);
+ }
+
+
+
+
+ @Override
+ public RelatedParts getRelatedParts ()
+ {
+ if (maRelatedParts == null)
+ {
+ maRelatedParts = new RelatedParts(
+ maPartName,
+ maPartManager);
+ }
+ return maRelatedParts;
+ }
+
+
+
+
+ private final ContentType meContentType;
+ private final PartManager maPartManager;
+ private final PartName maPartName;
+ private RelatedParts maRelatedParts;
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartManager.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartManager.java
new file mode 100644
index 000000000000..c61f16572487
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartManager.java
@@ -0,0 +1,145 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class PartManager
+{
+ public PartManager (final File aFile)
+ {
+ ZipFile aZipFile = null;
+ try
+ {
+ aZipFile = new ZipFile(aFile);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ maZipFile = aZipFile;
+ maPartNameToPartMap = new HashMap<>();
+ }
+
+
+
+
+ public InputStream getStreamForPartName (final PartName aPartName)
+ {
+ final ZipEntry aEntry = maZipFile.getEntry(
+ ToZipEntryName(aPartName.GetFullname()));
+ if (aEntry == null)
+ return null;
+
+ try
+ {
+ return maZipFile.getInputStream(aEntry);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+
+
+
+ /** This is the low-level variant of getStreamForPartName().
+ * It can return streams for entries in the OOXML zip package
+ * that are not, technically, parts.
+ * @return
+ * Returns null when the named stream does not exist or can not be
+ * opened.
+ */
+ public InputStream getStreamForStreamName (final String sStreamName)
+ {
+ final ZipEntry aEntry = maZipFile.getEntry(
+ ToZipEntryName(sStreamName));
+ try
+ {
+ return maZipFile.getInputStream(aEntry);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+
+
+
+ public ContentTypes getContentTypes ()
+ {
+ if (maContentTypes == null)
+ {
+ maContentTypes = new ContentTypes(this);
+ }
+ return maContentTypes;
+ }
+
+
+
+
+ private final String ToZipEntryName (final String sPath)
+ {
+ return sPath.substring(1);
+ }
+
+
+
+
+ /** Return a list of the names of all streams.
+ * Note that that list is not necessarily identical to the list of part
+ * names. It can contain entries that are not parts.
+ */
+ public final String[] listStreamNames ()
+ {
+ final Vector<String> aStreamNames = new Vector<>();
+
+ final Enumeration<? extends ZipEntry> aEntries = maZipFile.entries();
+ while (aEntries.hasMoreElements())
+ {
+ final ZipEntry aEntry = aEntries.nextElement();
+ aStreamNames.add(aEntry.getName());
+ }
+
+ return aStreamNames.toArray(new String[0]);
+ }
+
+
+
+
+ public Part getPart (final PartName aName)
+ {
+ SoftReference<Part> aSoftPart = maPartNameToPartMap.get(aName);
+ Part aPart = null;
+ if (aSoftPart != null)
+ aPart = aSoftPart.get();
+ if (aPart == null)
+ {
+ aPart = new Part(
+ getContentTypes().getTypeForPartName(aName),
+ this,
+ aName);
+ maPartNameToPartMap.put(aName, new SoftReference<Part>(aPart));
+ }
+
+ return aPart;
+ }
+
+
+
+
+ private ZipFile maZipFile;
+ private ContentTypes maContentTypes;
+ private final Map<PartName, SoftReference<Part>> maPartNameToPartMap;
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartManagerPrototype.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartManagerPrototype.java
new file mode 100644
index 000000000000..8aa820714d67
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartManagerPrototype.java
@@ -0,0 +1,33 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+import java.io.File;
+
+import org.apache.openoffice.ooxml.framework.part.parser.ParserFactory;
+import org.apache.openoffice.ooxml.parser.Log;
+
+public class PartManagerPrototype
+{
+ public static void main (final String ... aArgumentList)
+ {
+ if (aArgumentList.length != 3)
+ {
+ System.err.printf("usage: PartManagerPrototype <ooxml-file-name> <parser-table-filename> <log-filename>");
+ System.exit(1);
+ }
+
+ final long nStartTime = System.currentTimeMillis();
+
+ Log.Dbg = new Log(aArgumentList[2]);
+ ParserFactory.SetParserTableFilename(aArgumentList[1]);
+
+ final File aOOXMLFile = new File(aArgumentList[0]);
+ final Part aPart = OOXMLPackage.Create(aOOXMLFile).getOfficeDocumentPart().getPartById("rId1");
+
+ final long nEndTime = System.currentTimeMillis();
+
+ System.out.printf("got content type %s for %s in %fs\n",
+ aPart.getContentType(),
+ aPart.getPartName(),
+ (nEndTime-nStartTime)/1000.0);
+ }
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartName.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartName.java
new file mode 100644
index 000000000000..e91aa37eac49
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/PartName.java
@@ -0,0 +1,130 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+/** Operations around part names.
+ */
+public class PartName
+ implements Comparable<PartName>
+{
+ public PartName (final String sPath)
+ {
+ if ( ! (sPath.isEmpty() || sPath.startsWith("/")))
+ {
+ assert(sPath.isEmpty() || sPath.startsWith("/"));
+ }
+ assert(sPath.indexOf('\\') == -1);
+
+ msPath = sPath;
+ }
+
+
+
+
+ public PartName (
+ final String sPath,
+ final PartName aParentName,
+ final String sMode)
+ {
+ switch(sMode)
+ {
+ case "External":
+ msPath = sPath;
+ break;
+
+ case "Internal":
+ msPath = Cleanup(aParentName.GetPathname() + "/" + sPath);
+ break;
+
+ default:
+ throw new RuntimeException();
+ }
+ }
+
+
+
+
+ public PartName getRelationshipsPartName ()
+ {
+ return new PartName(GetPathname() + "/_rels/" + GetBasename() + ".rels");
+ }
+
+
+
+
+ private String GetPathname ()
+ {
+ if (msPath.isEmpty())
+ return "";
+ else
+ {
+ final int nPathnameEnd = msPath.lastIndexOf('/');
+ assert(nPathnameEnd>=0);
+ return msPath.substring(0, nPathnameEnd);
+ }
+ }
+
+
+
+
+ public String GetBasename ()
+ {
+ if (msPath.isEmpty())
+ return "";
+ else
+ {
+ final int nBasenameStart = msPath.lastIndexOf('/');
+ assert(nBasenameStart>=0);
+ return msPath.substring(nBasenameStart+1);
+ }
+ }
+
+
+
+
+ public String GetExtension ()
+ {
+ final int nExtensionStart = msPath.lastIndexOf('.');
+ if (nExtensionStart < 0)
+ return null;
+ else
+ return msPath.substring(nExtensionStart+1);
+ }
+
+
+
+
+ public String GetFullname()
+ {
+ return msPath;
+ }
+
+
+
+
+ @Override
+ public int compareTo (final PartName aOther)
+ {
+ return msPath.compareTo(aOther.msPath);
+ }
+
+
+
+
+ private String Cleanup (final String sName)
+ {
+ return sName.replaceAll("/[^/]+/\\.\\./", "/");
+ }
+
+
+
+
+ @Override
+ public String toString ()
+ {
+ return msPath;
+ }
+
+
+
+
+ private final String msPath;
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/RelatedParts.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/RelatedParts.java
new file mode 100644
index 000000000000..22cd218c9ab8
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/RelatedParts.java
@@ -0,0 +1,131 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import javax.xml.stream.Location;
+
+import org.apache.openoffice.ooxml.framework.part.parser.ParserFactory;
+import org.apache.openoffice.ooxml.parser.ElementContext;
+import org.apache.openoffice.ooxml.parser.Parser;
+import org.apache.openoffice.ooxml.parser.action.ActionTrigger;
+import org.apache.openoffice.ooxml.parser.action.IAction;
+
+public class RelatedParts
+{
+ RelatedParts (
+ final PartName aPartName,
+ final PartManager aPartManager)
+ {
+ maIdToTargetMap = new HashMap<>();
+ maTypeToTargetsMap = new HashMap<>();
+
+ final InputStream aStream = aPartManager.getStreamForPartName(aPartName.getRelationshipsPartName());
+ if (aStream != null)
+ {
+ final Parser aParser = ParserFactory.getParser(
+ ContentType.Relationships,
+ aStream,
+ null);
+ aParser.GetActionManager().AddElementStartAction(
+ "A_CT_Relationship",
+ new IAction()
+ {
+ @Override public void Run (
+ final ActionTrigger eTrigger,
+ final ElementContext aContext,
+ final String sText,
+ final Location aStartLocation,
+ final Location aEndLocation)
+ {
+ final String sId = aContext.GetAttributes().GetRawAttributeValue("A_Id");
+ final String sType = aContext.GetAttributes().GetRawAttributeValue("A_Type");
+ final String sTarget = aContext.GetAttributes().GetRawAttributeValue("A_Target");
+ String sTargetMode = aContext.GetAttributes().GetRawAttributeValue("A_TargetMode");
+ if (sTargetMode == null)
+ sTargetMode = "Internal";
+
+ AddRelationship(
+ sId,
+ RelationshipType.CreateFromString(sType),
+ new PartName(sTarget, aPartName, sTargetMode));
+ }
+ }
+ );
+ aParser.Parse();
+ }
+ }
+
+
+
+
+ private void AddRelationship (
+ final String sId,
+ final RelationshipType eType,
+ final PartName aTarget)
+ {
+ maIdToTargetMap.put(sId, aTarget);
+
+ Vector<PartName> aTargets = maTypeToTargetsMap.get(eType);
+ if (aTargets == null)
+ {
+ aTargets = new Vector<>();
+ maTypeToTargetsMap.put(eType, aTargets);
+ }
+ aTargets.add(aTarget);
+ }
+
+
+
+
+ public PartName GetTargetForId (final String sId)
+ {
+ return maIdToTargetMap.get(sId);
+ }
+
+
+
+
+ public Iterable<PartName> GetTargetsForType (final RelationshipType eType)
+ {
+ return maTypeToTargetsMap.get(eType);
+ }
+
+
+
+ public Iterable<PartName> getAllTargets ()
+ {
+ final Set<PartName> aAllNames = new TreeSet<>();
+ aAllNames.addAll(maIdToTargetMap.values());
+ return aAllNames;
+ }
+
+
+
+
+ public PartName GetSingleTargetForType (final RelationshipType eType)
+ {
+ if (maTypeToTargetsMap.get(eType).size() != 1)
+ {
+ System.out.printf("there are %d targets for relationship type %s\n",
+ maTypeToTargetsMap.get(eType).size(),
+ eType.toString());
+ for (final PartName aName : maTypeToTargetsMap.get(eType))
+ {
+ System.out.printf("%s\n", aName);
+ }
+ assert(false);
+ }
+ return maTypeToTargetsMap.get(eType).firstElement();
+ }
+
+
+
+
+ private final Map<String,PartName> maIdToTargetMap;
+ private final Map<RelationshipType, Vector<PartName>> maTypeToTargetsMap;
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/RelationshipType.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/RelationshipType.java
new file mode 100644
index 000000000000..3074d1b9b52a
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/RelationshipType.java
@@ -0,0 +1,112 @@
+package org.apache.openoffice.ooxml.framework.part;
+
+public enum RelationshipType
+{
+ ExtendedProperties,
+ CoreProperties,
+ OfficeDocument,
+ Image,
+ Header,
+ Hyperlink,
+ Styles,
+ EndNotes,
+ Footer,
+ Numbering,
+ CustomXML,
+ FootNotes,
+ WebSettings,
+ Theme,
+ Settings,
+ FontTable,
+ Thumbnail,
+ Slide,
+ ViewProperties,
+ PresentationProperties,
+ HandoutMaster,
+ TableStyles,
+ SlideMaster,
+ NotesMaster,
+ SlideLayout,
+ NotesSlide,
+ VMLDrawing,
+ OLE,
+ Chart,
+ Package,
+ ThemeOverride,
+
+ Unknown
+ ;
+
+ public static RelationshipType CreateFromString (final String sType)
+ {
+ switch(sType)
+ {
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties":
+ return ExtendedProperties;
+ case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties":
+ return CoreProperties;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument":
+ return OfficeDocument;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image":
+ return Image;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header":
+ return Header;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink":
+ return Hyperlink;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles":
+ return Styles;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes":
+ return EndNotes;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer":
+ return Footer;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering":
+ return Numbering;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml":
+ return CustomXML;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes":
+ return FootNotes;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings":
+ return WebSettings;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme":
+ return Theme;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings":
+ return Settings;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable":
+ return FontTable;
+ case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail":
+ return Thumbnail;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide":
+ return Slide;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps":
+ return ViewProperties;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps":
+ return PresentationProperties;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/handoutMaster":
+ return HandoutMaster;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles":
+ return TableStyles;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster":
+ return SlideMaster;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster":
+ return NotesMaster;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout":
+ return SlideLayout;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide":
+ return NotesSlide;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing":
+ return VMLDrawing;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject":
+ return OLE;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart":
+ return Chart;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package":
+ return Package;
+ case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/themeOverride":
+ return ThemeOverride;
+
+ default:
+ System.err.printf(sType +" is not yet supported\n");
+ return Unknown;
+ }
+ }
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/ContentTypesParser.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/ContentTypesParser.java
new file mode 100644
index 000000000000..0d64f10cb1c3
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/ContentTypesParser.java
@@ -0,0 +1,30 @@
+package org.apache.openoffice.ooxml.framework.part.parser;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Vector;
+
+import org.apache.openoffice.ooxml.parser.Parser;
+import org.apache.openoffice.ooxml.parser.StateMachine;
+
+public class ContentTypesParser
+ extends Parser
+{
+ public ContentTypesParser (
+ final InputStream aIn,
+ final String sParserTableFilename,
+ final Vector<String> aErrorsAndWarnings)
+ {
+ super(CreateStateMachine(sParserTableFilename, aErrorsAndWarnings), aIn);
+ }
+
+
+
+
+ private static StateMachine CreateStateMachine (
+ final String sParserTableFilename,
+ final Vector<String> aErrorsAndWarnings)
+ {
+ return new StateMachine(new File(sParserTableFilename), aErrorsAndWarnings);
+ }
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/ParserFactory.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/ParserFactory.java
new file mode 100644
index 000000000000..83a635ca4077
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/ParserFactory.java
@@ -0,0 +1,46 @@
+package org.apache.openoffice.ooxml.framework.part.parser;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Vector;
+
+import org.apache.openoffice.ooxml.framework.part.ContentType;
+import org.apache.openoffice.ooxml.parser.Parser;
+import org.apache.openoffice.ooxml.parser.StateMachine;
+
+public class ParserFactory
+{
+ public static Parser getParser (
+ final ContentType eType,
+ final InputStream aStream,
+ final Vector<String> aErrorsAndWarnings)
+ {
+ switch(eType)
+ {
+ case Relationships:
+ return new RelationshipParser(aStream, msParserTableFilename, aErrorsAndWarnings);
+
+ case ContentTypes:
+ return new ContentTypesParser(aStream, msParserTableFilename, aErrorsAndWarnings);
+
+ default:
+ return new Parser(
+ new StateMachine(new File(msParserTableFilename), aErrorsAndWarnings),
+ aStream);
+ }
+ }
+
+
+
+
+ public static void SetParserTableFilename (final String sFilename)
+ {
+ assert(new File(sFilename).exists());
+ msParserTableFilename = sFilename;
+ }
+
+
+
+
+ private static String msParserTableFilename = null;
+}
diff --git a/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/RelationshipParser.java b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/RelationshipParser.java
new file mode 100644
index 000000000000..bcbfd3344908
--- /dev/null
+++ b/ooxml/source/framework/JavaPartManager/src/org/apache/openoffice/ooxml/framework/part/parser/RelationshipParser.java
@@ -0,0 +1,30 @@
+package org.apache.openoffice.ooxml.framework.part.parser;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Vector;
+
+import org.apache.openoffice.ooxml.parser.Parser;
+import org.apache.openoffice.ooxml.parser.StateMachine;
+
+public class RelationshipParser
+ extends Parser
+{
+ public RelationshipParser (
+ final InputStream aIn,
+ final String sParserTableFilename,
+ final Vector<String> aErrorsAndWarnings)
+ {
+ super(CreateStateMachine(sParserTableFilename, aErrorsAndWarnings), aIn);
+ }
+
+
+
+
+ private static StateMachine CreateStateMachine (
+ final String sParserTableFilename,
+ final Vector<String> aErrorsAndWarnings)
+ {
+ return new StateMachine(new File(sParserTableFilename), aErrorsAndWarnings);
+ }
+}