Initial checkin of org.openoffice.idesupport java package for shared
classes supporting Office Scripting in Java in various IDEs
This commit is contained in:
477
scripting/java/org/openoffice/idesupport/zip/ParcelZipper.java
Normal file
477
scripting/java/org/openoffice/idesupport/zip/ParcelZipper.java
Normal file
@@ -0,0 +1,477 @@
|
||||
package org.openoffice.idesupport.zip;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.*;
|
||||
import java.beans.PropertyVetoException;
|
||||
|
||||
import org.openoffice.idesupport.filter.FileFilter;
|
||||
import org.openoffice.idesupport.filter.BinaryOnlyFilter;
|
||||
import org.openoffice.idesupport.filter.ExceptParcelFilter;
|
||||
|
||||
import org.openoffice.idesupport.xml.XMLParser;
|
||||
import org.openoffice.idesupport.xml.Manifest;
|
||||
|
||||
public class ParcelZipper
|
||||
{
|
||||
public static final String PARCEL_PREFIX_DIR = "Scripts/java/";
|
||||
public static final String PARCEL_EXTENSION = "sxp";
|
||||
public static final String CONTENTS_DIRNAME = "Contents";
|
||||
public static final String PARCEL_DESCRIPTOR_XML = "parcel-descriptor.xml";
|
||||
|
||||
private static ParcelZipper zipper = null;
|
||||
private static XMLParser parser = null;
|
||||
|
||||
private static final FileFilter DEFAULT_FILTER =
|
||||
BinaryOnlyFilter.getInstance();
|
||||
|
||||
private ParcelZipper() {
|
||||
}
|
||||
|
||||
public static ParcelZipper getParcelZipper() {
|
||||
if (zipper == null) {
|
||||
synchronized(ParcelZipper.class) {
|
||||
if (zipper == null)
|
||||
zipper = new ParcelZipper();
|
||||
}
|
||||
}
|
||||
return zipper;
|
||||
}
|
||||
|
||||
public static void setXMLParser(XMLParser parser) {
|
||||
getParcelZipper().parser = parser;
|
||||
}
|
||||
|
||||
public String zipParcel(File basedir) throws IOException {
|
||||
File targetfile, targetdir;
|
||||
|
||||
if (basedir.getName().equals(CONTENTS_DIRNAME))
|
||||
targetdir = basedir.getParentFile();
|
||||
else
|
||||
targetdir = basedir;
|
||||
|
||||
targetfile = new File(targetdir, targetdir.getName() + "." + PARCEL_EXTENSION);
|
||||
|
||||
return zipParcel(basedir, targetfile, DEFAULT_FILTER);
|
||||
}
|
||||
|
||||
public String zipParcel(File basedir, File targetfile) throws IOException {
|
||||
return zipParcel(basedir, targetfile, DEFAULT_FILTER);
|
||||
}
|
||||
|
||||
public String zipParcel(File basedir, FileFilter filter) throws IOException {
|
||||
File targetfile, targetdir;
|
||||
|
||||
if (basedir.getName().equals(CONTENTS_DIRNAME))
|
||||
targetdir = basedir.getParentFile();
|
||||
else
|
||||
targetdir = basedir;
|
||||
|
||||
targetfile = new File(targetdir, targetdir.getName() + "." + PARCEL_EXTENSION);
|
||||
|
||||
return zipParcel(basedir, targetfile, filter);
|
||||
}
|
||||
|
||||
public String zipParcel(File basedir, File targetfile, FileFilter filter)
|
||||
throws IOException {
|
||||
String realpath, tmppath;
|
||||
|
||||
realpath = targetfile.getPath();
|
||||
tmppath = realpath + ".tmp";
|
||||
|
||||
File tmpfile = new File(tmppath);
|
||||
try {
|
||||
if (tmpfile.exists() == true)
|
||||
tmpfile.delete();
|
||||
|
||||
ZipOutputStream out =
|
||||
new ZipOutputStream(new FileOutputStream(tmpfile));
|
||||
|
||||
File[] children = basedir.listFiles();
|
||||
for (int i = 0; i < children.length; i++)
|
||||
addFileToParcel(children[i], "", out, filter);
|
||||
|
||||
out.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
tmpfile.delete();
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
if (targetfile.exists() == true)
|
||||
targetfile.delete();
|
||||
tmpfile.renameTo(targetfile);
|
||||
return targetfile.getAbsolutePath();
|
||||
}
|
||||
|
||||
private void addFileToParcel(File root, String path, ZipOutputStream out, FileFilter filter)
|
||||
throws IOException {
|
||||
ZipEntry ze;
|
||||
|
||||
if (root.isDirectory() == true) {
|
||||
ze = new ZipEntry(/* PARCEL_PREFIX_DIR + */ path + root.getName() + "/");
|
||||
out.putNextEntry(ze);
|
||||
out.closeEntry();
|
||||
File[] children = root.listFiles();
|
||||
|
||||
for (int i = 0; i < children.length; i++)
|
||||
addFileToParcel(children[i], path + root.getName() + "/", out, filter);
|
||||
}
|
||||
else {
|
||||
if (filter.validate(root.getName()) == false &&
|
||||
root.getName().equals("parcel-descriptor.xml") == false)
|
||||
return;
|
||||
|
||||
ze = new ZipEntry(/* PARCEL_PREFIX_DIR + */ path + root.getName());
|
||||
out.putNextEntry(ze);
|
||||
|
||||
byte[] bytes = new byte[1024];
|
||||
int len;
|
||||
FileInputStream fis = new FileInputStream(root);
|
||||
|
||||
while ((len = fis.read(bytes)) != -1)
|
||||
out.write(bytes, 0, len);
|
||||
|
||||
out.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOverwriteNeeded(File parcel, File target) {
|
||||
boolean result;
|
||||
|
||||
if (target.isDirectory())
|
||||
result = isDirectoryOverwriteNeeded(parcel, target);
|
||||
else
|
||||
result = isDocumentOverwriteNeeded(parcel, target);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isDirectoryOverwriteNeeded(File parcel, File target) {
|
||||
String parcelDir = getParcelDirFromParcelZip(parcel.getName());
|
||||
File[] children = target.listFiles();
|
||||
|
||||
for (int i = 0; i < children.length; i++)
|
||||
if (children[i].getName().equals(parcelDir))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isDocumentOverwriteNeeded(File parcel, File document) {
|
||||
ZipFile documentZip;
|
||||
|
||||
try {
|
||||
documentZip = new ZipFile(document);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String name =
|
||||
PARCEL_PREFIX_DIR + getParcelDirFromParcelZip(parcel.getName()) +
|
||||
"/" + PARCEL_DESCRIPTOR_XML;
|
||||
|
||||
if (documentZip.getEntry(name) != null)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String deployParcel(File parcel, File target)
|
||||
throws IOException {
|
||||
|
||||
String output = null;
|
||||
if (target.isDirectory())
|
||||
output = unzipToDirectory(parcel, target);
|
||||
else
|
||||
output = unzipToZip(parcel, target);
|
||||
return output;
|
||||
}
|
||||
|
||||
private String getParcelDirFromParcelZip(String zipname) {
|
||||
String result = zipname.substring(0, zipname.lastIndexOf("."));
|
||||
return result;
|
||||
}
|
||||
|
||||
private String unzipToDirectory(File parcel, File targetDirectory)
|
||||
throws IOException {
|
||||
|
||||
ZipInputStream in;
|
||||
File parcelDir = new File(targetDirectory,
|
||||
getParcelDirFromParcelZip(parcel.getName()));
|
||||
|
||||
if (isDirectoryOverwriteNeeded(parcel, targetDirectory)) {
|
||||
if (deleteDir(parcelDir) == false) {
|
||||
throw new IOException("Could not overwrite: " +
|
||||
parcelDir.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
in = new ZipInputStream(new FileInputStream(parcel));
|
||||
|
||||
File outFile;
|
||||
ZipEntry inEntry = in.getNextEntry();
|
||||
byte[] bytes = new byte[1024];
|
||||
int len;
|
||||
|
||||
while (inEntry != null) {
|
||||
outFile = new File(parcelDir, inEntry.getName());
|
||||
if (inEntry.isDirectory()) {
|
||||
//System.err.println("Creating directory: " + outFile.getAbsolutePath());
|
||||
outFile.mkdir();
|
||||
}
|
||||
else {
|
||||
if (outFile.getParentFile().exists() != true)
|
||||
outFile.getParentFile().mkdirs();
|
||||
|
||||
FileOutputStream out = new FileOutputStream(outFile);
|
||||
// System.out.println("Writing file: " + outFile.getAbsolutePath());
|
||||
while ((len = in.read(bytes)) != -1)
|
||||
out.write(bytes, 0, len);
|
||||
out.close();
|
||||
}
|
||||
|
||||
inEntry = in.getNextEntry();
|
||||
}
|
||||
in.close();
|
||||
return parcelDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
private boolean deleteDir(File basedir) {
|
||||
if (basedir.isDirectory()) {
|
||||
String[] children = basedir.list();
|
||||
for (int i=0; i<children.length; i++) {
|
||||
boolean success = deleteDir(new File(basedir, children[i]));
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return basedir.delete();
|
||||
}
|
||||
|
||||
private String unzipToZip(File parcel, File targetDocument)
|
||||
throws IOException {
|
||||
|
||||
ZipInputStream documentStream, parcelStream;
|
||||
ZipOutputStream outStream;
|
||||
Manifest manifest;
|
||||
|
||||
if (isDocumentOverwriteNeeded(parcel, targetDocument)) {
|
||||
String parcelName = getParcelDirFromParcelZip(parcel.getName());
|
||||
unzipToZipExceptParcel(targetDocument, parcelName);
|
||||
}
|
||||
|
||||
// first write contents of document to tmpfile
|
||||
File tmpfile = new File(targetDocument.getAbsolutePath() + ".tmp");
|
||||
|
||||
manifest = addParcelToManifest(targetDocument, parcel);
|
||||
|
||||
documentStream =
|
||||
new ZipInputStream(new FileInputStream(targetDocument));
|
||||
parcelStream = new ZipInputStream(new FileInputStream(parcel));
|
||||
outStream = new ZipOutputStream(new FileOutputStream(tmpfile));
|
||||
|
||||
try {
|
||||
copyParcelToZip(parcelStream, outStream, PARCEL_PREFIX_DIR +
|
||||
getParcelDirFromParcelZip(parcel.getName()));
|
||||
copyDocumentToZip(documentStream, outStream, manifest);
|
||||
documentStream.close();
|
||||
parcelStream.close();
|
||||
outStream.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
tmpfile.delete();
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
if (targetDocument.delete() == false) {
|
||||
tmpfile.delete();
|
||||
throw new IOException("Could not overwrite " + targetDocument);
|
||||
}
|
||||
else
|
||||
tmpfile.renameTo(targetDocument);
|
||||
|
||||
return targetDocument.getAbsolutePath();
|
||||
}
|
||||
|
||||
private void copyParcelToZip(ZipInputStream in, ZipOutputStream out,
|
||||
String parcelName) throws IOException {
|
||||
|
||||
ZipEntry outEntry;
|
||||
ZipEntry inEntry = in.getNextEntry();
|
||||
byte[] bytes = new byte[1024];
|
||||
int len;
|
||||
|
||||
while (inEntry != null) {
|
||||
if(parcelName!=null)
|
||||
outEntry = new ZipEntry(parcelName + "/" + inEntry.getName());
|
||||
else
|
||||
outEntry = new ZipEntry(inEntry);
|
||||
out.putNextEntry(outEntry);
|
||||
|
||||
if (inEntry.isDirectory() == false)
|
||||
while ((len = in.read(bytes)) != -1)
|
||||
out.write(bytes, 0, len);
|
||||
|
||||
out.closeEntry();
|
||||
inEntry = in.getNextEntry();
|
||||
}
|
||||
}
|
||||
|
||||
private void copyDocumentToZip(ZipInputStream in, ZipOutputStream out,
|
||||
Manifest manifest) throws IOException {
|
||||
|
||||
ZipEntry outEntry;
|
||||
ZipEntry inEntry;
|
||||
byte[] bytes = new byte[1024];
|
||||
int len;
|
||||
|
||||
while ((inEntry = in.getNextEntry()) != null) {
|
||||
|
||||
outEntry = new ZipEntry(inEntry);
|
||||
out.putNextEntry(outEntry);
|
||||
|
||||
if(inEntry.getName().equals("META-INF/manifest.xml") &&
|
||||
manifest != null) {
|
||||
InputStream manifestStream = manifest.getInputStream();
|
||||
while ((len = manifestStream.read(bytes)) != -1)
|
||||
out.write(bytes, 0, len);
|
||||
}
|
||||
else if (inEntry.isDirectory() == false) {
|
||||
while ((len = in.read(bytes)) != -1)
|
||||
out.write(bytes, 0, len);
|
||||
}
|
||||
|
||||
out.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
public String unzipToZipExceptParcel(File document, String parcelName)
|
||||
throws IOException {
|
||||
|
||||
ZipInputStream documentStream;
|
||||
ZipOutputStream outStream;
|
||||
Manifest manifest = null;
|
||||
|
||||
parcelName = PARCEL_PREFIX_DIR + parcelName;
|
||||
manifest = removeParcelFromManifest(document, parcelName);
|
||||
|
||||
// first write contents of document to tmpfile
|
||||
File tmpfile = new File(document.getAbsolutePath() + ".tmp");
|
||||
|
||||
documentStream = new ZipInputStream(new FileInputStream(document));
|
||||
outStream = new ZipOutputStream(new FileOutputStream(tmpfile));
|
||||
|
||||
try {
|
||||
ZipEntry outEntry;
|
||||
ZipEntry inEntry;
|
||||
byte[] bytes = new byte[1024];
|
||||
int len;
|
||||
|
||||
while ((inEntry = documentStream.getNextEntry()) != null) {
|
||||
|
||||
if(inEntry.getName().startsWith(parcelName))
|
||||
continue;
|
||||
|
||||
outEntry = new ZipEntry(inEntry);
|
||||
outStream.putNextEntry(outEntry);
|
||||
|
||||
if(inEntry.getName().equals("META-INF/manifest.xml") &&
|
||||
manifest != null) {
|
||||
InputStream manifestStream = manifest.getInputStream();
|
||||
while ((len = manifestStream.read(bytes)) != -1)
|
||||
outStream.write(bytes, 0, len);
|
||||
}
|
||||
else if (inEntry.isDirectory() == false) {
|
||||
while ((len = documentStream.read(bytes)) != -1)
|
||||
outStream.write(bytes, 0, len);
|
||||
}
|
||||
|
||||
outStream.closeEntry();
|
||||
}
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
tmpfile.delete();
|
||||
throw ioe;
|
||||
}
|
||||
finally {
|
||||
documentStream.close();
|
||||
outStream.close();
|
||||
}
|
||||
|
||||
if (document.delete() == false) {
|
||||
tmpfile.delete();
|
||||
throw new IOException("Could not overwrite " + document);
|
||||
}
|
||||
else
|
||||
tmpfile.renameTo(document);
|
||||
|
||||
return document.getAbsolutePath();
|
||||
}
|
||||
|
||||
private Manifest getManifestFromDocument(File document) {
|
||||
ZipFile documentZip;
|
||||
Manifest result = null;
|
||||
|
||||
try {
|
||||
documentZip = new ZipFile(document);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ZipEntry original = documentZip.getEntry("META-INF/manifest.xml");
|
||||
if (original == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
result = new Manifest(documentZip.getInputStream(original), parser);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Manifest addParcelToManifest(File document, File parcel) {
|
||||
ZipFile documentZip, parcelZip;
|
||||
Manifest result = null;
|
||||
|
||||
result = getManifestFromDocument(document);
|
||||
if (result == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
parcelZip = new ZipFile(parcel);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String prefix = PARCEL_PREFIX_DIR +
|
||||
getParcelDirFromParcelZip(parcel.getName()) + "/";
|
||||
|
||||
Enumeration entries = parcelZip.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry)entries.nextElement();
|
||||
result.add(prefix + entry.getName());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Manifest removeParcelFromManifest(File document, String name) {
|
||||
Manifest result = null;
|
||||
|
||||
result = getManifestFromDocument(document);
|
||||
if (result == null)
|
||||
return null;
|
||||
|
||||
result.remove(name);
|
||||
return result;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user