OpenDocumentParserNoTempFileTest.java
/*
* 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.tika.parser.odf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.apache.tika.TikaTest;
import org.apache.tika.detect.DefaultDetector;
import org.apache.tika.detect.Detector;
import org.apache.tika.io.CacheMemoryBudget;
import org.apache.tika.io.TemporaryResources;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaCoreProperties;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.BodyContentHandler;
/**
* Inline pictures were spooled to a temp file before detection; with rewind support the
* entry stays in memory. Watching the temp directory cannot see this -- each entry gets its
* own TemporaryResources -- so the assertion is on the stream the detector is handed.
*/
public class OpenDocumentParserNoTempFileTest extends TikaTest {
/** Records whether each inline picture reached detection backed by a file. */
private static class SpyDetector implements Detector {
private final Detector delegate = new DefaultDetector();
private final List<Boolean> pictureHadFile = new ArrayList<>();
@Override
public MediaType detect(TikaInputStream input, Metadata metadata, ParseContext context)
throws IOException {
String type = metadata.get(TikaCoreProperties.EMBEDDED_RESOURCE_TYPE);
if (TikaCoreProperties.EmbeddedResourceType.INLINE.toString().equals(type)) {
pictureHadFile.add(input.hasFile());
}
return delegate.detect(input, metadata, context);
}
}
@Test
public void testInlinePicturesAreDetectedFromMemory() throws Exception {
byte[] bytes;
try (InputStream is = getResourceAsStream("/test-documents/testODTEmbedded.odt")) {
bytes = is.readAllBytes();
}
SpyDetector spy = new SpyDetector();
ParseContext context = new ParseContext();
context.set(Detector.class, spy);
context.set(CacheMemoryBudget.class, new CacheMemoryBudget(64L * 1024 * 1024));
Metadata metadata = new Metadata();
BodyContentHandler handler = new BodyContentHandler();
try (TemporaryResources tmp = new TemporaryResources()) {
TikaInputStream tis = TikaInputStream.get(new ByteArrayInputStream(bytes), tmp, metadata);
new OpenDocumentParser().parse(tis, handler, metadata, context);
}
assertFalse(spy.pictureHadFile.isEmpty(), "no inline picture reached detection");
for (Boolean hadFile : spy.pictureHadFile) {
assertFalse(hadFile, "inline picture was spooled to disk before detection");
}
assertTrue(handler.toString().length() > 0, "content was extracted");
}
/** The picture must be re-readable after detection, or the embedded parse sees nothing. */
@Test
public void testEmbeddedPicturesStillParseAfterRewind() throws Exception {
List<Metadata> metadataList = getRecursiveMetadata("testODTEmbedded.odt");
boolean sawImage = false;
for (Metadata m : metadataList) {
assertEquals(null, m.get(TikaCoreProperties.EMBEDDED_EXCEPTION),
"embedded exception for " + m.get(TikaCoreProperties.RESOURCE_NAME_KEY));
String type = m.get(TikaCoreProperties.EMBEDDED_RESOURCE_TYPE);
if (TikaCoreProperties.EmbeddedResourceType.INLINE.toString().equals(type)) {
sawImage = true;
}
}
assertTrue(sawImage, "no inline picture in the recursive metadata");
}
}