You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/03/09 15:21:35 UTC
svn commit: r635243 - in /poi/branches/ooxml/src/ooxml: java/org/apache/poi/
java/org/apache/poi/xslf/ java/org/apache/poi/xslf/extractor/
java/org/apache/poi/xslf/usermodel/ testcases/org/apache/poi/
testcases/org/apache/poi/xslf/ testcases/org/apache...
Author: nick
Date: Sun Mar 9 07:21:34 2008
New Revision: 635243
URL: http://svn.apache.org/viewvc?rev=635243&view=rev
Log:
Get the powerpoint ooxml stuff converted over, and fix up a few tests
Added:
poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java
- copied, changed from r635031, poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/HSLFXML.java
poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java
- copied, changed from r635031, poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/HXFPowerPointExtractor.java
poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
- copied, changed from r635031, poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/HSLFXMLSlideShow.java
poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java
- copied, changed from r635031, poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestHSLFXML.java
Removed:
poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/HSLFXML.java
poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/HXFPowerPointExtractor.java
poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/HSLFXMLSlideShow.java
poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestHSLFXML.java
Modified:
poi/branches/ooxml/src/ooxml/java/org/apache/poi/POIXMLDocument.java
poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/TestDetectAsOOXML.java
poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/extractor/TestHXFPowerPointExtractor.java
Modified: poi/branches/ooxml/src/ooxml/java/org/apache/poi/POIXMLDocument.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/ooxml/java/org/apache/poi/POIXMLDocument.java?rev=635243&r1=635242&r2=635243&view=diff
==============================================================================
--- poi/branches/ooxml/src/ooxml/java/org/apache/poi/POIXMLDocument.java (original)
+++ poi/branches/ooxml/src/ooxml/java/org/apache/poi/POIXMLDocument.java Sun Mar 9 07:21:34 2008
@@ -22,15 +22,19 @@
import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.util.IOUtils;
+import org.apache.xmlbeans.XmlException;
import org.openxml4j.exceptions.InvalidFormatException;
import org.openxml4j.exceptions.OpenXML4JException;
import org.openxml4j.opc.Package;
import org.openxml4j.opc.PackagePart;
import org.openxml4j.opc.PackagePartName;
import org.openxml4j.opc.PackageRelationship;
+import org.openxml4j.opc.PackageRelationshipCollection;
import org.openxml4j.opc.PackageRelationshipTypes;
import org.openxml4j.opc.PackagingURIHelper;
-
+import org.openxml4j.opc.internal.PackagePropertiesPart;
+import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties;
+import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument;
public abstract class POIXMLDocument {
@@ -68,7 +72,7 @@
* in the event of a problem.
* Works around shortcomings in java's this() constructor calls
*/
- protected static Package openPackage(String path) throws IOException {
+ public static Package openPackage(String path) throws IOException {
try {
return Package.open(path);
} catch (InvalidFormatException e) {
@@ -99,6 +103,27 @@
}
return part;
}
+
+ /**
+ * Fetches the (single) PackagePart which is defined as
+ * the supplied relation content type of the base
+ * container, or null if none found.
+ * @param relationType The relation content type to search for
+ * @throws IllegalArgumentException If we find more than one part of that type
+ */
+ protected PackagePart getSinglePartByRelationType(String relationType) throws IllegalArgumentException, OpenXML4JException {
+ PackageRelationshipCollection rels =
+ getCorePart().getRelationshipsByType(relationType);
+ if(rels.size() == 0) {
+ return null;
+ }
+ if(rels.size() > 1) {
+ throw new IllegalArgumentException("Found " + rels.size() + " relations for the type " + relationType + ", should only ever be one!");
+ }
+ PackageRelationship rel = rels.getRelationship(0);
+ return getTargetPart(rel);
+ }
+
/**
* Checks that the supplied InputStream (which MUST
@@ -132,4 +157,30 @@
header[3] == POIFSConstants.OOXML_FILE_HEADER[3]
);
}
+
+ /**
+ * Get the core document properties (core ooxml properties).
+ * TODO: Replace with nice usermodel wrapper
+ * @deprecated To be replaced with a proper user-model style view of the properties
+ */
+ public PackagePropertiesPart getCoreProperties() throws OpenXML4JException, IOException {
+ PackagePart propsPart = getSinglePartByRelationType(CORE_PROPERTIES_REL_TYPE);
+ if(propsPart == null) {
+ return null;
+ }
+ return (PackagePropertiesPart)propsPart;
+ }
+
+ /**
+ * Get the extended document properties (extended ooxml properties)
+ * TODO: Replace with nice usermodel wrapper
+ * @deprecated To be replaced with a proper user-model style view of the properties
+ */
+ public CTProperties getExtendedProperties() throws OpenXML4JException, XmlException, IOException {
+ PackagePart propsPart = getSinglePartByRelationType(EXTENDED_PROPERTIES_REL_TYPE);
+
+ PropertiesDocument props = PropertiesDocument.Factory.parse(
+ propsPart.getInputStream());
+ return props.getProperties();
+ }
}
Copied: poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java (from r635031, poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/HSLFXML.java)
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java?p2=poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java&p1=poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/HSLFXML.java&r1=635031&r2=635243&rev=635243&view=diff
==============================================================================
--- poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/HSLFXML.java (original)
+++ poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java Sun Mar 9 07:21:34 2008
@@ -14,11 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-package org.apache.poi.hslf;
+package org.apache.poi.xslf;
import java.io.IOException;
-import org.apache.poi.hxf.HXFDocument;
+import org.apache.poi.POIXMLDocument;
import org.apache.xmlbeans.XmlException;
import org.openxml4j.exceptions.InvalidFormatException;
import org.openxml4j.exceptions.OpenXML4JException;
@@ -49,7 +49,7 @@
*
* WARNING - APIs expected to change rapidly
*/
-public class HSLFXML extends HXFDocument {
+public class XSLFSlideShow extends POIXMLDocument {
public static final String MAIN_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml";
public static final String NOTES_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml";
public static final String SLIDE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml";
@@ -58,11 +58,14 @@
private PresentationDocument presentationDoc;
- public HSLFXML(Package container) throws OpenXML4JException, IOException, XmlException {
- super(container, MAIN_CONTENT_TYPE);
+ public XSLFSlideShow(Package container) throws OpenXML4JException, IOException, XmlException {
+ super(container);
presentationDoc =
- PresentationDocument.Factory.parse(basePart.getInputStream());
+ PresentationDocument.Factory.parse(getCorePart().getInputStream());
+ }
+ public XSLFSlideShow(String file) throws OpenXML4JException, IOException, XmlException {
+ this(openPackage(file));
}
/**
@@ -96,11 +99,16 @@
* the supplied slide master reference
*/
public CTSlideMaster getSlideMaster(CTSlideMasterIdListEntry master) throws IOException, XmlException {
- PackagePart masterPart =
- getRelatedPackagePart(master.getId2());
- SldMasterDocument masterDoc =
- SldMasterDocument.Factory.parse(masterPart.getInputStream());
- return masterDoc.getSldMaster();
+ try {
+ PackagePart masterPart =
+ getTargetPart(getCorePart().getRelationship(master.getId2()));
+
+ SldMasterDocument masterDoc =
+ SldMasterDocument.Factory.parse(masterPart.getInputStream());
+ return masterDoc.getSldMaster();
+ } catch(InvalidFormatException e) {
+ throw new XmlException(e);
+ }
}
/**
@@ -108,11 +116,15 @@
* the supplied slide reference
*/
public CTSlide getSlide(CTSlideIdListEntry slide) throws IOException, XmlException {
- PackagePart slidePart =
- getRelatedPackagePart(slide.getId2());
- SldDocument slideDoc =
- SldDocument.Factory.parse(slidePart.getInputStream());
- return slideDoc.getSld();
+ try {
+ PackagePart slidePart =
+ getTargetPart(getCorePart().getRelationship(slide.getId2()));
+ SldDocument slideDoc =
+ SldDocument.Factory.parse(slidePart.getInputStream());
+ return slideDoc.getSld();
+ } catch(InvalidFormatException e) {
+ throw new XmlException(e);
+ }
}
/**
@@ -120,11 +132,11 @@
* slide, as found from the supplied slide reference
*/
public CTNotesSlide getNotes(CTSlideIdListEntry slide) throws IOException, XmlException {
- PackagePart slidePart =
- getRelatedPackagePart(slide.getId2());
-
PackageRelationshipCollection notes;
try {
+ PackagePart slidePart =
+ getTargetPart(getCorePart().getRelationship(slide.getId2()));
+
notes = slidePart.getRelationshipsByType(NOTES_RELATION_TYPE);
} catch(InvalidFormatException e) {
throw new IllegalStateException(e);
@@ -138,11 +150,15 @@
throw new IllegalStateException("Expecting 0 or 1 notes for a slide, but found " + notes.size());
}
- PackagePart notesPart =
- getPackagePart(notes.getRelationship(0));
- NotesDocument notesDoc =
- NotesDocument.Factory.parse(notesPart.getInputStream());
-
- return notesDoc.getNotes();
+ try {
+ PackagePart notesPart =
+ getTargetPart(notes.getRelationship(0));
+ NotesDocument notesDoc =
+ NotesDocument.Factory.parse(notesPart.getInputStream());
+
+ return notesDoc.getNotes();
+ } catch(InvalidFormatException e) {
+ throw new IllegalStateException(e);
+ }
}
}
Copied: poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java (from r635031, poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/HXFPowerPointExtractor.java)
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java?p2=poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java&p1=poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/HXFPowerPointExtractor.java&r1=635031&r2=635243&rev=635243&view=diff
==============================================================================
--- poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/HXFPowerPointExtractor.java (original)
+++ poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java Sun Mar 9 07:21:34 2008
@@ -14,15 +14,14 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-package org.apache.poi.hslf.extractor;
+package org.apache.poi.xslf.extractor;
import java.io.File;
import java.io.IOException;
+import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLTextExtractor;
-import org.apache.poi.hslf.HSLFXML;
-import org.apache.poi.hslf.usermodel.HSLFXMLSlideShow;
-import org.apache.poi.hxf.HXFDocument;
+import org.apache.poi.xslf.XSLFSlideShow;
import org.apache.xmlbeans.XmlException;
import org.openxml4j.exceptions.OpenXML4JException;
import org.openxml4j.opc.Package;
@@ -35,17 +34,15 @@
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
-public class HXFPowerPointExtractor extends POIXMLTextExtractor {
- private HSLFXMLSlideShow slideshow;
+public class XSLFPowerPointExtractor extends POIXMLTextExtractor {
+ private XSLFSlideShow slideshow;
private boolean slidesByDefault = true;
private boolean notesByDefault = false;
- public HXFPowerPointExtractor(Package container) throws XmlException, OpenXML4JException, IOException {
- this(new HSLFXMLSlideShow(
- new XSLFXML(container)
- ));
+ public XSLFPowerPointExtractor(Package container) throws XmlException, OpenXML4JException, IOException {
+ this(new XSLFSlideShow(container));
}
- public HXFPowerPointExtractor(HSLFXMLSlideShow slideshow) {
+ public XSLFPowerPointExtractor(XSLFSlideShow slideshow) {
super(slideshow);
this.slideshow = slideshow;
}
@@ -57,9 +54,8 @@
System.exit(1);
}
POIXMLTextExtractor extractor =
- new HXFPowerPointExtractor(HXFDocument.openPackage(
- new File(args[0])
- ));
+ new XSLFPowerPointExtractor(
+ new XSLFSlideShow(args[0]));
System.out.println(extractor.getText());
}
@@ -94,13 +90,13 @@
StringBuffer text = new StringBuffer();
CTSlideIdListEntry[] slideRefs =
- slideshow._getHSLFXML().getSlideReferences().getSldIdArray();
+ slideshow.getSlideReferences().getSldIdArray();
for (int i = 0; i < slideRefs.length; i++) {
try {
CTSlide slide =
- slideshow._getHSLFXML().getSlide(slideRefs[i]);
+ slideshow.getSlide(slideRefs[i]);
CTNotesSlide notes =
- slideshow._getHSLFXML().getNotes(slideRefs[i]);
+ slideshow.getNotes(slideRefs[i]);
if(slideText) {
extractText(slide.getCSld().getSpTree(), text);
Copied: poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java (from r635031, poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/HSLFXMLSlideShow.java)
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java?p2=poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java&p1=poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/HSLFXMLSlideShow.java&r1=635031&r2=635243&rev=635243&view=diff
==============================================================================
--- poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/HSLFXMLSlideShow.java (original)
+++ poi/branches/ooxml/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java Sun Mar 9 07:21:34 2008
@@ -14,10 +14,9 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-package org.apache.poi.hslf.usermodel;
+package org.apache.poi.xslf.usermodel;
-import org.apache.poi.POIXMLDocument;
-import org.apache.poi.hslf.HSLFXML;
+import org.apache.poi.xslf.XSLFSlideShow;
/**
* High level representation of a ooxml slideshow.
@@ -25,15 +24,17 @@
* they are reading or writing a slideshow. It is also the
* top level object for creating new slides/etc.
*/
-public class HSLFXMLSlideShow extends POIXMLDocument {
- private org.apache.poi.hslf.XSLFXML hslfXML;
+public class XMLSlideShow {
+ private XSLFSlideShow slideShow;
- public HSLFXMLSlideShow(XSLFXML xml) {
- super(xml);
- this.hslfXML = xml;
+ public XMLSlideShow(XSLFSlideShow xml) {
+ this.slideShow = xml;
}
- public XSLFXML _getHSLFXML() {
- return hslfXML;
+ public XSLFSlideShow _getXSLFSlideShow() {
+ return slideShow;
}
+
+ // TODO: Get slides
+ // TODO: Get notes
}
Modified: poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/TestDetectAsOOXML.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/TestDetectAsOOXML.java?rev=635243&r1=635242&r2=635243&view=diff
==============================================================================
--- poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/TestDetectAsOOXML.java (original)
+++ poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/TestDetectAsOOXML.java Sun Mar 9 07:21:34 2008
@@ -17,7 +17,7 @@
==================================================================== */
-package org.apache.poi.hxf;
+package org.apache.poi;
import junit.framework.TestCase;
import java.io.*;
@@ -38,7 +38,7 @@
{
File f = new File(dirname + "/sample.xlsx");
- HXFDocument.openPackage(f);
+ POIXMLDocument.openPackage(f.toString());
}
public void testDetectAsPOIFS() throws Exception {
@@ -48,18 +48,18 @@
in = new PushbackInputStream(
new FileInputStream(dirname + "/SampleSS.xlsx"), 10
);
- assertTrue(HXFDocument.hasOOXMLHeader(in));
+ assertTrue(POIXMLDocument.hasOOXMLHeader(in));
// xls file isn't
in = new PushbackInputStream(
new FileInputStream(dirname + "/SampleSS.xls"), 10
);
- assertFalse(HXFDocument.hasOOXMLHeader(in));
+ assertFalse(POIXMLDocument.hasOOXMLHeader(in));
// text file isn't
in = new PushbackInputStream(
new FileInputStream(dirname + "/SampleSS.txt"), 10
);
- assertFalse(HXFDocument.hasOOXMLHeader(in));
+ assertFalse(POIXMLDocument.hasOOXMLHeader(in));
}
}
Copied: poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java (from r635031, poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestHSLFXML.java)
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java?p2=poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java&p1=poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestHSLFXML.java&r1=635031&r2=635243&rev=635243&view=diff
==============================================================================
--- poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestHSLFXML.java (original)
+++ poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java Sun Mar 9 07:21:34 2008
@@ -14,11 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-package org.apache.poi.hslf;
+package org.apache.poi.xslf;
import java.io.File;
-import org.apache.poi.hxf.HXFDocument;
+import org.apache.poi.POIXMLDocument;
import org.openxml4j.opc.Package;
import org.openxml4j.opc.PackagePart;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
@@ -26,8 +26,8 @@
import junit.framework.TestCase;
-public class TestHSLFXML extends TestCase {
- private File sampleFile;
+public class TestXSLFSlideShow extends TestCase {
+ private String sampleFile;
protected void setUp() throws Exception {
super.setUp();
@@ -35,15 +35,15 @@
sampleFile = new File(
System.getProperty("HSLF.testdata.path") +
File.separator + "sample.pptx"
- );
+ ).toString();
}
public void testContainsMainContentType() throws Exception {
- Package pack = HXFDocument.openPackage(sampleFile);
+ Package pack = POIXMLDocument.openPackage(sampleFile);
boolean found = false;
for(PackagePart part : pack.getParts()) {
- if(part.getContentType().equals(HSLFXML.MAIN_CONTENT_TYPE)) {
+ if(part.getContentType().equals(XSLFSlideShow.MAIN_CONTENT_TYPE)) {
found = true;
}
System.out.println(part);
@@ -52,13 +52,13 @@
}
public void testOpen() throws Exception {
- HXFDocument.openPackage(sampleFile);
+ POIXMLDocument.openPackage(sampleFile);
- HSLFXML xml;
+ XSLFSlideShow xml;
// With the finalised uri, should be fine
- xml = new HSLFXML(
- HXFDocument.openPackage(sampleFile)
+ xml = new XSLFSlideShow(
+ POIXMLDocument.openPackage(sampleFile)
);
// Check the core
@@ -74,9 +74,7 @@
}
public void testSlideBasics() throws Exception {
- HSLFXML xml = new HSLFXML(
- HXFDocument.openPackage(sampleFile)
- );
+ XSLFSlideShow xml = new XSLFSlideShow(sampleFile);
// Should have 1 master
assertEquals(1, xml.getSlideMasterReferences().sizeOfSldMasterIdArray());
@@ -110,9 +108,7 @@
}
public void testMetadataBasics() throws Exception {
- HSLFXML xml = new HSLFXML(
- HXFDocument.openPackage(sampleFile)
- );
+ XSLFSlideShow xml = new XSLFSlideShow(sampleFile);
assertNotNull(xml.getCoreProperties());
assertNotNull(xml.getExtendedProperties());
Modified: poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/extractor/TestHXFPowerPointExtractor.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/extractor/TestHXFPowerPointExtractor.java?rev=635243&r1=635242&r2=635243&view=diff
==============================================================================
--- poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/extractor/TestHXFPowerPointExtractor.java (original)
+++ poi/branches/ooxml/src/ooxml/testcases/org/apache/poi/xslf/extractor/TestHXFPowerPointExtractor.java Sun Mar 9 07:21:34 2008
@@ -49,7 +49,7 @@
*/
public void testGetSimpleText() throws Exception {
new HXFPowerPointExtractor(xmlA.getPackage());
- new HXFPowerPointExtractor(new HSLFXMLSlideShow(xmlA));
+ new HXFPowerPointExtractor(new XMLSlideShow(xmlA));
HXFPowerPointExtractor extractor =
new HXFPowerPointExtractor(xmlA.getPackage());
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org