mirror of https://github.com/apache/poi.git
Add a POIFS Helper FilteringDirectoryNode, which wraps a DirectoryEntry and allows certain parts to be ignored
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1207412 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
bf477712be
commit
65fb35e5a0
|
@ -34,6 +34,7 @@
|
|||
|
||||
<changes>
|
||||
<release version="3.8-beta5" date="2011-??-??">
|
||||
<action dev="poi-developers" type="add">POIFS Helper FilteringDirectoryNode, which wraps a DirectoryEntry and allows certain parts to be ignored</action>
|
||||
<action dev="poi-developers" type="fix">52209 - fixed inserting multiple pictures in XSLF </action>
|
||||
<action dev="poi-developers" type="fix">51803 - fixed HSLF TextExtractor to extract content from master slide </action>
|
||||
<action dev="poi-developers" type="fix">52190 - null check on XWPF setFontFamily</action>
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
|
||||
/* ====================================================================
|
||||
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.poi.poifs.filesystem;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.poi.hpsf.ClassID;
|
||||
|
||||
/**
|
||||
* A DirectoryEntry filter, which exposes another
|
||||
* DirectoryEntry less certain parts.
|
||||
* This is typically used when copying or comparing
|
||||
* Filesystems.
|
||||
*/
|
||||
public class FilteringDirectoryNode implements DirectoryEntry
|
||||
{
|
||||
/**
|
||||
* The names of our entries to exclude
|
||||
*/
|
||||
private Set<String> excludes;
|
||||
/**
|
||||
* Excludes of our child directories
|
||||
*/
|
||||
private Map<String,List<String>> childExcludes;
|
||||
|
||||
private DirectoryEntry directory;
|
||||
|
||||
/**
|
||||
* Creates a filter round the specified directory, which
|
||||
* will exclude entries such as "MyNode" and "MyDir/IgnoreNode".
|
||||
* The excludes can stretch into children, if they contain a /.
|
||||
*
|
||||
* @param entry The Directory to filter
|
||||
* @param excludes The Entries to exclude
|
||||
*/
|
||||
public FilteringDirectoryNode(DirectoryEntry directory, Collection<String> excludes) {
|
||||
this.directory = directory;
|
||||
|
||||
// Process the excludes
|
||||
this.excludes = new HashSet<String>();
|
||||
this.childExcludes = new HashMap<String, List<String>>();
|
||||
for (String excl : excludes) {
|
||||
int splitAt = excl.indexOf('/');
|
||||
if (splitAt == -1) {
|
||||
// Applies to us
|
||||
this.excludes.add(excl);
|
||||
} else {
|
||||
// Applies to a child
|
||||
String child = excl.substring(0, splitAt);
|
||||
String childExcl = excl.substring(splitAt+1);
|
||||
if (! this.childExcludes.containsKey(child)) {
|
||||
this.childExcludes.put(child, new ArrayList<String>());
|
||||
}
|
||||
this.childExcludes.get(child).add(childExcl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DirectoryEntry createDirectory(String name) throws IOException {
|
||||
return directory.createDirectory(name);
|
||||
}
|
||||
|
||||
public DocumentEntry createDocument(String name, InputStream stream)
|
||||
throws IOException {
|
||||
return directory.createDocument(name, stream);
|
||||
}
|
||||
|
||||
public DocumentEntry createDocument(String name, int size,
|
||||
POIFSWriterListener writer) throws IOException {
|
||||
return directory.createDocument(name, size, writer);
|
||||
}
|
||||
|
||||
public Iterator<Entry> getEntries() {
|
||||
return new FilteringIterator();
|
||||
}
|
||||
|
||||
public Iterator<Entry> iterator() {
|
||||
return getEntries();
|
||||
}
|
||||
|
||||
public int getEntryCount() {
|
||||
int size = directory.getEntryCount();
|
||||
for (String excl : excludes) {
|
||||
if (directory.hasEntry(excl)) {
|
||||
size--;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (getEntryCount() == 0);
|
||||
}
|
||||
|
||||
public boolean hasEntry(String name) {
|
||||
if (excludes.contains(name)) {
|
||||
return false;
|
||||
}
|
||||
return directory.hasEntry(name);
|
||||
}
|
||||
|
||||
public Entry getEntry(String name) throws FileNotFoundException {
|
||||
if (excludes.contains(name)) {
|
||||
throw new FileNotFoundException(name);
|
||||
}
|
||||
|
||||
Entry entry = directory.getEntry(name);
|
||||
return wrapEntry(entry);
|
||||
}
|
||||
private Entry wrapEntry(Entry entry) {
|
||||
String name = entry.getName();
|
||||
if (childExcludes.containsKey(name) && entry instanceof DirectoryEntry) {
|
||||
return new FilteringDirectoryNode(
|
||||
(DirectoryEntry)entry, childExcludes.get(name));
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
public ClassID getStorageClsid() {
|
||||
return directory.getStorageClsid();
|
||||
}
|
||||
|
||||
public void setStorageClsid(ClassID clsidStorage) {
|
||||
directory.setStorageClsid(clsidStorage);
|
||||
}
|
||||
|
||||
public boolean delete() {
|
||||
return directory.delete();
|
||||
}
|
||||
|
||||
public boolean renameTo(String newName) {
|
||||
return directory.renameTo(newName);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return directory.getName();
|
||||
}
|
||||
|
||||
public DirectoryEntry getParent() {
|
||||
return directory.getParent();
|
||||
}
|
||||
|
||||
public boolean isDirectoryEntry() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isDocumentEntry() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private class FilteringIterator implements Iterator<Entry> {
|
||||
private Iterator<Entry> parent;
|
||||
private Entry next;
|
||||
|
||||
private FilteringIterator() {
|
||||
parent = directory.getEntries();
|
||||
locateNext();
|
||||
}
|
||||
private void locateNext() {
|
||||
next = null;
|
||||
Entry e;
|
||||
while (parent.hasNext() && next == null) {
|
||||
e = parent.next();
|
||||
if (! excludes.contains(e.getName())) {
|
||||
next = wrapEntry(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return (next != null);
|
||||
}
|
||||
|
||||
public Entry next() {
|
||||
Entry e = next;
|
||||
locateNext();
|
||||
return e;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Remove not supported");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
|
||||
/* ====================================================================
|
||||
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.poi.poifs.filesystem;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Class to test FilteringDirectoryNode functionality
|
||||
*/
|
||||
public final class TestFilteringDirectoryNode extends TestCase {
|
||||
private POIFSFileSystem fs;
|
||||
private DirectoryEntry dirA;
|
||||
private DirectoryEntry dirAA;
|
||||
private DirectoryEntry dirB;
|
||||
private DocumentEntry eRoot;
|
||||
private DocumentEntry eA;
|
||||
private DocumentEntry eAA;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
fs = new POIFSFileSystem();
|
||||
dirA = fs.createDirectory("DirA");
|
||||
dirB = fs.createDirectory("DirB");
|
||||
dirAA = dirA.createDirectory("DirAA");
|
||||
eRoot = fs.getRoot().createDocument("Root", new ByteArrayInputStream(new byte[] {}));
|
||||
eA = dirA.createDocument("NA", new ByteArrayInputStream(new byte[] {}));
|
||||
eAA = dirAA.createDocument("NAA", new ByteArrayInputStream(new byte[] {}));
|
||||
}
|
||||
|
||||
public void testNoFiltering() throws Exception {
|
||||
FilteringDirectoryNode d = new FilteringDirectoryNode(fs.getRoot(), new HashSet<String>());
|
||||
assertEquals(3, d.getEntryCount());
|
||||
assertEquals(dirA.getName(), d.getEntry(dirA.getName()).getName());
|
||||
|
||||
assertEquals(true, d.getEntry(dirA.getName()).isDirectoryEntry());
|
||||
assertEquals(false, d.getEntry(dirA.getName()).isDocumentEntry());
|
||||
|
||||
assertEquals(true, d.getEntry(dirB.getName()).isDirectoryEntry());
|
||||
assertEquals(false, d.getEntry(dirB.getName()).isDocumentEntry());
|
||||
|
||||
assertEquals(false, d.getEntry(eRoot.getName()).isDirectoryEntry());
|
||||
assertEquals(true, d.getEntry(eRoot.getName()).isDocumentEntry());
|
||||
|
||||
Iterator<Entry> i = d.getEntries();
|
||||
assertEquals(dirA, i.next());
|
||||
assertEquals(dirB, i.next());
|
||||
assertEquals(eRoot, i.next());
|
||||
assertEquals(null, i.next());
|
||||
}
|
||||
|
||||
public void testChildFiltering() throws Exception {
|
||||
List<String> excl = Arrays.asList(new String[] {"NotThere","AlsoNotThere", eRoot.getName()});
|
||||
FilteringDirectoryNode d = new FilteringDirectoryNode(fs.getRoot(), excl);
|
||||
|
||||
assertEquals(2, d.getEntryCount());
|
||||
assertEquals(true, d.hasEntry(dirA.getName()));
|
||||
assertEquals(true, d.hasEntry(dirB.getName()));
|
||||
assertEquals(false, d.hasEntry(eRoot.getName()));
|
||||
|
||||
assertEquals(dirA, d.getEntry(dirA.getName()));
|
||||
assertEquals(dirB, d.getEntry(dirB.getName()));
|
||||
try {
|
||||
d.getEntry(eRoot.getName());
|
||||
fail("Should be filtered");
|
||||
} catch(FileNotFoundException e) {}
|
||||
|
||||
Iterator<Entry> i = d.getEntries();
|
||||
assertEquals(dirA, i.next());
|
||||
assertEquals(dirB, i.next());
|
||||
assertEquals(null, i.next());
|
||||
|
||||
|
||||
// Filter more
|
||||
excl = Arrays.asList(new String[] {"NotThere","AlsoNotThere", eRoot.getName(), dirA.getName()});
|
||||
d = new FilteringDirectoryNode(fs.getRoot(), excl);
|
||||
|
||||
assertEquals(1, d.getEntryCount());
|
||||
assertEquals(false, d.hasEntry(dirA.getName()));
|
||||
assertEquals(true, d.hasEntry(dirB.getName()));
|
||||
assertEquals(false, d.hasEntry(eRoot.getName()));
|
||||
|
||||
try {
|
||||
d.getEntry(dirA.getName());
|
||||
fail("Should be filtered");
|
||||
} catch(FileNotFoundException e) {}
|
||||
assertEquals(dirB, d.getEntry(dirB.getName()));
|
||||
try {
|
||||
d.getEntry(eRoot.getName());
|
||||
fail("Should be filtered");
|
||||
} catch(FileNotFoundException e) {}
|
||||
|
||||
i = d.getEntries();
|
||||
assertEquals(dirB, i.next());
|
||||
assertEquals(null, i.next());
|
||||
|
||||
|
||||
// Filter everything
|
||||
excl = Arrays.asList(new String[] {"NotThere", eRoot.getName(), dirA.getName(), dirB.getName()});
|
||||
d = new FilteringDirectoryNode(fs.getRoot(), excl);
|
||||
|
||||
assertEquals(0, d.getEntryCount());
|
||||
assertEquals(false, d.hasEntry(dirA.getName()));
|
||||
assertEquals(false, d.hasEntry(dirB.getName()));
|
||||
assertEquals(false, d.hasEntry(eRoot.getName()));
|
||||
|
||||
try {
|
||||
d.getEntry(dirA.getName());
|
||||
fail("Should be filtered");
|
||||
} catch(FileNotFoundException e) {}
|
||||
try {
|
||||
d.getEntry(dirB.getName());
|
||||
fail("Should be filtered");
|
||||
} catch(FileNotFoundException e) {}
|
||||
try {
|
||||
d.getEntry(eRoot.getName());
|
||||
fail("Should be filtered");
|
||||
} catch(FileNotFoundException e) {}
|
||||
|
||||
i = d.getEntries();
|
||||
assertEquals(null, i.next());
|
||||
}
|
||||
|
||||
public void testNestedFiltering() throws Exception {
|
||||
List<String> excl = Arrays.asList(new String[] {
|
||||
dirA.getName()+"/"+"MadeUp",
|
||||
dirA.getName()+"/"+eA.getName(),
|
||||
dirA.getName()+"/"+dirAA.getName()+"/Test",
|
||||
eRoot.getName()
|
||||
});
|
||||
FilteringDirectoryNode d = new FilteringDirectoryNode(fs.getRoot(), excl);
|
||||
|
||||
// Check main
|
||||
assertEquals(2, d.getEntryCount());
|
||||
assertEquals(true, d.hasEntry(dirA.getName()));
|
||||
assertEquals(true, d.hasEntry(dirB.getName()));
|
||||
assertEquals(false, d.hasEntry(eRoot.getName()));
|
||||
|
||||
// Check filtering down
|
||||
assertEquals(true, d.getEntry(dirA.getName()) instanceof FilteringDirectoryNode);
|
||||
assertEquals(false, d.getEntry(dirB.getName()) instanceof FilteringDirectoryNode);
|
||||
|
||||
DirectoryEntry fdA = (DirectoryEntry)d.getEntry(dirA.getName());
|
||||
assertEquals(false, fdA.hasEntry(eA.getName()));
|
||||
assertEquals(true, fdA.hasEntry(dirAA.getName()));
|
||||
|
||||
DirectoryEntry fdAA = (DirectoryEntry)fdA.getEntry(dirAA.getName());
|
||||
assertEquals(true, fdAA.hasEntry(eAA.getName()));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue