blob: 902d5dc4a94e6ba1cc7e1617cb3253ae090f6a20 [file] [log] [blame]
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
package org.eclipse.compare;
import java.io.*;
import java.util.Iterator;
import java.util.HashMap;
import java.util.zip.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.util.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.compare.*;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.compare.internal.Utilities;
public class ZipFileStructureCreator implements IStructureCreator {
/**
* Common base class for ZipFolder and ZipFile
*/
static abstract class ZipResource implements IStructureComparator, ITypedElement {
private String fName;
ZipResource(String name) {
fName= name;
}
public String getName() {
return fName;
}
public Image getImage() {
return CompareUI.getImage(getType());
}
/**
* Returns true if other is ITypedElement and names are equal.
* @see IComparator#equals
*/
public boolean equals(Object other) {
if (other instanceof ITypedElement)
return fName.equals(((ITypedElement) other).getName());
return super.equals(other);
}
public int hashCode() {
return fName.hashCode();
}
}
static class ZipFolder extends ZipResource {
private HashMap fChildren= new HashMap(10);
ZipFolder(String name) {
super(name);
}
public String getType() {
return ITypedElement.FOLDER_TYPE;
}
public Object[] getChildren() {
Object[] children= new Object[fChildren.size()];
Iterator iter= fChildren.values().iterator();
for (int i= 0; iter.hasNext(); i++)
children[i]= iter.next();
return children;
}
ZipFile createContainer(String path) {
String entry= path;
int pos= path.indexOf('/');
if (pos < 0)
pos= path.indexOf('\\');
if (pos >= 0) {
entry= path.substring(0, pos);
path= path.substring(pos + 1);
} else if (entry.length() > 0) {
ZipFile ze= new ZipFile(entry);
fChildren.put(entry, ze);
return ze;
} else
return null;
ZipFolder folder= null;
if (fChildren != null) {
Object o= fChildren.get(entry);
if (o instanceof ZipFolder)
folder= (ZipFolder) o;
}
if (folder == null) {
folder= new ZipFolder(entry);
fChildren.put(entry, folder);
}
return folder.createContainer(path);
}
}
static class ZipFile extends ZipResource implements IStreamContentAccessor {
private byte[] fContents;
ZipFile(String name) {
super(name);
}
public String getType() {
String s= this.getName();
int pos= s.lastIndexOf('.');
if (pos >= 0)
return s.substring(pos + 1);
return ITypedElement.UNKNOWN_TYPE;
}
public Object[] getChildren() {
return null;
}
public InputStream getContents() {
if (fContents == null)
fContents= new byte[0];
return new ByteArrayInputStream(fContents);
}
byte[] getBytes() {
return fContents;
}
void setBytes(byte[] buffer) {
fContents= buffer;
}
void appendBytes(byte[] buffer, int length) {
if (length > 0) {
int oldLen= 0;
if (fContents != null)
oldLen= fContents.length;
byte[] newBuf= new byte[oldLen + length];
if (oldLen > 0)
System.arraycopy(fContents, 0, newBuf, 0, oldLen);
System.arraycopy(buffer, 0, newBuf, oldLen, length);
fContents= newBuf;
}
}
}
private String fTitle;
public ZipFileStructureCreator() {
this(Utilities.getString("ZipStructureCreator.name")); //$NON-NLS-1$
}
public ZipFileStructureCreator(String title) {
fTitle= title;
}
public String getName() {
return fTitle;
}
public IStructureComparator getStructure(Object input) {
InputStream is= null;
if (input instanceof IStreamContentAccessor) {
IStreamContentAccessor sca= (IStreamContentAccessor) input;
try {
is= sca.getContents();
} catch (CoreException ex) {
}
}
if (is == null)
return null;
ZipInputStream zip= new ZipInputStream(is);
ZipFolder root= new ZipFolder(""); //$NON-NLS-1$
try {
for (;;) {
ZipEntry entry= zip.getNextEntry();
if (entry == null)
break;
ZipFile ze= root.createContainer(entry.getName());
if (ze != null) {
int length= (int) entry.getSize();
if (length >= 0) {
byte[] buffer= new byte[length];
int offset= 0;
do {
int n= zip.read(buffer, offset, length);
offset += n;
length -= n;
} while (length > 0);
ze.setBytes(buffer);
} else {
byte[] buffer= new byte[1024];
int n;
do {
n= zip.read(buffer, 0, 1024);
ze.appendBytes(buffer, n);
} while (n >= 0);
}
}
zip.closeEntry();
}
} catch (IOException ex) {
return null;
} finally {
try {
zip.close();
} catch (IOException ex) {
}
}
if (root.fChildren.size() == 1) {
Iterator iter= root.fChildren.values().iterator();
return (IStructureComparator) iter.next();
}
return root;
}
public String getContents(Object o, boolean ignoreWhitespace) {
if (o instanceof ZipFile) {
byte[] bytes= ((ZipFile)o).getBytes();
if (bytes != null)
return new String(bytes);
return ""; //$NON-NLS-1$
}
return null;
}
/**
* Returns <code>false</code> since we cannot update a zip archive.
*/
public boolean canSave() {
return false;
}
/**
* Throws <code>AssertionFailedException</code> since we cannot update a zip archive.
*/
public void save(IStructureComparator structure, Object input) {
Assert.isTrue(false); // Cannot update zip archive
}
public IStructureComparator locate(Object path, Object source) {
return null;
}
public boolean canRewriteTree() {
return false;
}
public void rewriteTree(Differencer diff, IDiffContainer root) {
}
}