deepdiff.scope.ZipDiffUnit Maven / Gradle / Ivy
/*
* Copyright 2011 DeepDiff Contributors
*
* Licensed 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 deepdiff.scope;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import deepdiff.core.DiffUnit;
/**
* An implementation of {@link DiffUnit} for the comparison of two entries
* within a Zip file.
*/
class ZipDiffUnit implements DiffUnit {
private ZipEntry e1;
private ZipEntry e2;
private ZipInputStream zis1;
private ZipInputStream zis2;
private ZipDiffScope scope;
/**
* Initializes a new ZipDiffUnit object. Note that the {@link InputStream}s
* should not be closed. They are shared between all diff units in the
* scope, and the scope will handle closing them when processing is
* finished.
*
* @param scope the scope that the Zip entries are located within
* @param zis1 the {@link InputStream} to use to access the content of the
* left entry; may be null
* @param zis2 the {@link InputStream} to use to access the content of the
* right entry; may be null
* @param e1 the left entry; may be null
* @param e2 the right entry; may be null
*/
ZipDiffUnit(ZipDiffScope scope, ZipInputStream zis1,
ZipInputStream zis2, ZipEntry e1, ZipEntry e2) {
this.scope = scope;
this.zis1 = zis1;
this.zis2 = zis2;
this.e1 = e1;
this.e2 = e2;
}
/**
* Returns whether the left entry exists
*
* @return whether the left entry exists
*/
public boolean leftExists() {
return e1 != null;
}
/**
* Returns whether the right entry exists
*
* @return whether the right entry exists
*/
public boolean rightExists() {
return e2 != null;
}
/**
* Returns whether the left entry represents a directory
*
* @return whether the left entry represents a directory
*/
public boolean leftIsDir() {
return leftExists() && e1.isDirectory();
}
/**
* Returns whether the right entry represents a directory
*
* @return whether the right entry represents a directory
*/
public boolean rightIsDir() {
return rightExists() && e2.isDirectory();
}
/**
* Returns a stream to access the content of the left entry
*
* @return a stream to access the content of the left entry
*
* @throws IOException if there was an error creating the stream
*/
public InputStream getLeftInputStream() throws IOException {
return new UnclosableInputStream(zis1);
}
/**
* Returns a stream to access the content of the right entry
*
* @return a stream to access the content of the right entry
*
* @throws IOException if there was an error creating the stream
*/
public InputStream getRightInputStream() throws IOException {
return new UnclosableInputStream(zis2);
}
/**
* Returns the scoped path for the unit. This is the path of the Zip scope,
* followed by the path of the entry within the Zip scope
*
* @return the scoped path for the unit
*/
public String getScopedPath() {
String scopePath = scope.getPath();
String relativePath = null;
if (e1 != null) {
relativePath = e1.getName();
} else if (e2 != null) {
relativePath = e2.getName();
}
return scopePath + "!" + relativePath;
}
/**
* Implementation of InputStream that forbids the use of {@link #close()}.
* This is needed because there are some standard utility classes that
* automatically close streams that they are passed, such as {@link
* javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream)}. If the
* {@link ZipInputStream} is closed, no further entries in the scope could
* be processed.
*/
private static class UnclosableInputStream extends FilterInputStream {
/**
* Initializes a new UnclosableInputStream object.
*
* @param in the {@link InputStream} to delegate to
*/
protected UnclosableInputStream(InputStream in) {
super(in);
}
/**
* Does nothing.
*/
public final void close() {
//Do not close
}
}
}