diff options
Diffstat (limited to 'scripting/java/org/openoffice/netbeans/modules/office/filesystem/OpenOfficeDocFileSystem.java')
-rw-r--r-- | scripting/java/org/openoffice/netbeans/modules/office/filesystem/OpenOfficeDocFileSystem.java | 1182 |
1 files changed, 0 insertions, 1182 deletions
diff --git a/scripting/java/org/openoffice/netbeans/modules/office/filesystem/OpenOfficeDocFileSystem.java b/scripting/java/org/openoffice/netbeans/modules/office/filesystem/OpenOfficeDocFileSystem.java deleted file mode 100644 index 6081445d258a..000000000000 --- a/scripting/java/org/openoffice/netbeans/modules/office/filesystem/OpenOfficeDocFileSystem.java +++ /dev/null @@ -1,1182 +0,0 @@ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * 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 . - */ - -package org.openoffice.netbeans.modules.office.filesystem; - -import java.beans.*; -import java.io.*; -import java.util.*; -import java.util.zip.*; - -import org.openide.ErrorManager; -import org.openide.filesystems.*; -import org.openide.filesystems.FileSystem; // override java.io.FileSystem -import org.openide.util.NbBundle; - -// ISSUES: -// - This FS saves (updates) the file on 'setDocument' or 'removeNotify'. -// It has to let the user to decide to update or not. - -// TODOS: -// - 'Update' action on the mounted document which saves all recent modifications. -// - To introduce 'scope' editable property to control editable portion of -// the mounted document. -// - Acceptable document type identification before mount. - -/** - * OpenOffice.org Document filesystem. - */ -public class OpenOfficeDocFileSystem - extends AbstractFileSystem { - public static final String SCRIPTS_ROOT = "Scripts"; // must be a folder - public static final String SEPARATOR = "/"; // zip file separator - - private static final int OS_UNKNOWN = 0; - private static final int OS_UNIX = 1; - private static final int OS_MACOS = 2; - private static final int OS_WINDOWS = 3; - - private static final int REFRESH_OFF = -1; // -1 is desabled - private static final int REFRESH_TIME = REFRESH_OFF; // (mS) - private static final String TMP_FILE_PREF = "sx_"; - private static final String TMP_FILE_SUFX = ".sxx"; - - private transient Map cache; // filesystem cache - private transient File docFile; // OpenOffice document - private transient ZipFile zipFile; - - private static transient int osType; // type of OS - - private transient ChildrenStrategy childrenStrategy; - private transient EditableStrategy editableStrategy; - - private transient boolean isModified; // true if an entry has been removed - - /** - * Static constructor. - */ - static { - // Identify the type of OS - String osname = System.getProperty("os.name"); - - if (osname.startsWith("Mac OS")) - osType = OS_MACOS; - else if (osname.startsWith("Windows")) - osType = OS_WINDOWS; - else - osType = OS_UNIX; - } - - /** - * Default constructor. Initializes new OpenOffice filesystem. - */ - public OpenOfficeDocFileSystem() { - // Create the filesystem cache - cache = new HashMap(); - - // Initialize strategies - editableStrategy = new EditableStrategy(SCRIPTS_ROOT); - childrenStrategy = new ChildrenStrategy(); - - // Create and use implementations of filesystem functionality: - info = new InfoImpl(); - change = new ChangeImpl(); - - // Handle filesystem.attributes files normally: - DefaultAttributes defattr = new DefaultAttributes( - info, change, new ListImpl()); - - // Handle filesystem.attributes files normally + adds virtual attribute - // "java.io.File" that is used in conversion routines FileUtil.toFile and - // FileUtil.fromFile - //defattr = new InnerAttrs(this, info, change, new ListImpl()); - // (Otherwise set attr to a special implementation, and use ListImpl for list.) - attr = defattr; - list = defattr; - - setRefreshTime(REFRESH_OFF); - } - - /** - * Constructor. Initializes new OpenOffice filesystem with FS capability. - */ - public OpenOfficeDocFileSystem(FileSystemCapability cap) { - this(); - setCapability(cap); - } - - /** - * Provides unique signature of an instance of the filesystem. - * NOTE: The scope is not a part of the signature so it is impossible - * to mount the same archive more than once. - */ - public static String computeSystemName(File file) { - return OpenOfficeDocFileSystem.class.getName() + "[" + file + "]"; - } - - // ----------- PROPERTIES -------------- - - /** - * Provides the 'human readable' name of the instance of the filesystem. - */ - public String getDisplayName() { - if (!isValid()) - return NbBundle.getMessage(OpenOfficeDocFileSystem.class, - "LAB_invalid_file_system", ((docFile != null) ? docFile.toString() : "")); - else - return NbBundle.getMessage(OpenOfficeDocFileSystem.class, - "LAB_valid_file_system", docFile.toString()); - } - - /** - * Retrieves the 'document' property. - */ - public File getDocument() { - return docFile; - } - - /** - * Sets the 'document' property. - */ - // Bean setter. Changing the OpenOffice document (or in general, the identity - // of the root file object) should cause everything using this filesystem - // to refresh. The system name must change and refreshRoot should be used - // to ensure that everything is correctly updated. - - public synchronized void setDocument(File file) - throws java.beans.PropertyVetoException, java.io.IOException { - System.out.println("OpenOfficeDocFileSystem.setDocument: file=\"" + - file.toString() + "\""); - - if (!file.exists() || !file.isFile()) { - IOException ioe = new IOException( - file.toString() + " does not exist"); - ErrorManager.getDefault().annotate(ioe, NbBundle.getMessage( - OpenOfficeDocFileSystem.class, "EXC_root_dir_does_not_exist", - file.toString())); - throw ioe; - } - - // update the document - try { - updateDocument(); - } catch (IOException ioe) { - // cannot save all!!! - System.out.println("*** OpenOfficeDocFileSystem.setDocument:"); - System.out.println(" file: " + ((docFile != null) ? docFile.toString() : - "")); - System.out.println(" exception: " + ioe.getMessage()); - } - - // new document type verification!!! - closeDocument(); - - // open a new document - try { - openDocument(file); - firePropertyChange(PROP_ROOT, null, refreshRoot()); - setRefreshTime(REFRESH_TIME); - } catch (IOException ioe) { - // cannot open a new document!!! - System.out.println("*** OpenOfficeDocFileSystem.setDocument:"); - System.out.println(" file: " + ((file != null) ? file.toString() : "")); - System.out.println(" exception: " + ioe.getMessage()); - } - } - - /** - * Retrieves 'readonly' property. - * NOTE: The portion of the mounted document available to the user is - * always editable. - */ - public boolean isReadOnly() { - return false; - } - - /** - * Sets 'readonly' property. - * NOTE: The portion of the mounted document available to the user is - * always editable. - */ - public void setReadOnly(boolean flag) { - // sorry! it is not supported. - } - - // ----------- SPECIAL CAPABILITIES -------------- - - /** - * Participates in the environment configuration. - * This is how you can affect the classpath for execution, compilation, etc. - */ - public void prepareEnvironment(FileSystem.Environment environment) { - // BUG: the compiller cannot access files within the OpenOffice document. - //environment.addClassPath(docFile.toString()); - } - - /* ----------------------------------------------------------- - * Affect the name and icon of files on this filesystem according to their - * "status", e.g. version-control modification-commit state: - /* - private class StatusImpl implements Status { - public Image annotateIcon(Image icon, int iconType, Set files) { - // You may first modify it, e.g. by adding a check mark to the icon - // if that makes sense for this file or group of files. - return icon; - } - public String annotateName(String name, Set files) { - // E.g. add some sort of suffix to the name if some of the - // files are modified but not backed up or committed somehow: - if (theseFilesAreModified(files)) - return NbBundle.getMessage(OpenOfficeDocFileSystem.class, "LBL_modified_files", name); - else - return name; - } - } - - private transient Status status; - - public Status getStatus() { - if (status == null) { - status = new StatusImpl(); - } - return status; - } - // And use fireFileStatusChanged whenever you know something has changed. - */ - - /* - // Filesystem-specific actions, such as version-control operations. - // The actions should typically be CookieActions looking for DataObject - // cookies, where the object's primary file is on this type of filesystem. - public SystemAction[] getActions() { - // ------>>>> UPDATE OPENOFFICE DOCUMENT <<<<------ - return new SystemAction[] { - SystemAction.get(SomeAction.class), - null, // separator - SystemAction.get(SomeOtherAction.class) - }; - } - */ - - /** - * Notifies this filesystem that it has been removed from the repository. - * Concrete filesystem implementations could perform clean-up here. - * The default implementation does nothing. - * <p>Note that this method is <em>advisory</em> and serves as an optimization - * to avoid retaining resources for too long etc. Filesystems should maintain correct - * semantics regardless of whether and when this method is called. - */ - public void removeNotify() { - setRefreshTime(REFRESH_OFF); // disable refresh - - // update the document - try { - updateDocument(); - } catch (IOException ioe) { - // cannot save all!!! - System.out.println("*** OpenOfficeDocFileSystem.removeNotify:"); - System.out.println(" exception: " + ioe.getMessage()); - } - - closeDocument(); - super.removeNotify(); - } - - /* - * Opens (mounts) an OpenOffice document. - */ - private void openDocument(File file) - throws IOException, PropertyVetoException { - synchronized (cache) { - setSystemName(computeSystemName(file)); - docFile = file; - zipFile = new ZipFile(docFile); - cacheDocument(zipFile.entries(), editableStrategy); - isModified = false; - } // synchronized - } - - /* - * Closes the document and cleans up the cache. - */ - private void closeDocument() { - synchronized (cache) { - // if a document mounted - close it - if (docFile != null) { - // close the document archive - if (zipFile != null) { - try { - zipFile.close(); - } catch (IOException ioe) { - // sorry! we can do nothing about it. - } - } - - zipFile = null; - // clean up cache - scanDocument(new CleanStrategy()); - docFile = null; - isModified = false; - } - } // synchronized - } - - /* - * Creates a document cache. - */ - private void cacheDocument(Enumeration entries, Strategy editables) { - Entry cacheEntry; - ZipEntry archEntry; - - synchronized (cache) { - cache.clear(); - // root folder - cacheEntry = new ReadWriteEntry(null); - cache.put(cacheEntry.getName(), cacheEntry); - - // the rest of items - while (entries.hasMoreElements()) { - archEntry = (ZipEntry)entries.nextElement(); - cacheEntry = new Entry(archEntry); - - if (editables.evaluate(cacheEntry)) - cacheEntry = new ReadWriteEntry(archEntry); - - cache.put(cacheEntry.getName(), cacheEntry); - } - } // synchronized - } - - /* - * Updates the document. - */ - private void updateDocument() - throws IOException { - if (docFile == null) - return; - - synchronized (cache) { - ModifiedStrategy modifiedStrategy = new ModifiedStrategy(); - scanDocument(modifiedStrategy); - - if (isModified || modifiedStrategy.isModified()) { - File tmpFile = null; - - try { - // create updated document - tmpFile = File.createTempFile( - TMP_FILE_PREF, TMP_FILE_SUFX, docFile.getParentFile()); - saveDocument(tmpFile); - } catch (IOException ioe) { - if (tmpFile != null) - tmpFile.delete(); - - throw ioe; - } - - // close the document archive - if (zipFile != null) { - try { - zipFile.close(); - } catch (IOException ioe) { - } - } - - zipFile = null; - // create the document and backup - File newFile = new File(docFile.getParentFile() + File.separator + - "~" + docFile.getName()); - - if (newFile.exists()) - newFile.delete(); // delete old backup - - docFile.renameTo(newFile); - tmpFile.renameTo(docFile); - // open the document archive - zipFile = new ZipFile(docFile); - } - - isModified = false; - } // synchronized - } - - /* - * Saves the document in a new archive. - */ - private void saveDocument(File file) - throws IOException { - synchronized (cache) { - SaveStrategy saver = new SaveStrategy(file); - scanDocument(saver); - saver.close(); - } // synchronized - } - - /* - * Provides each individual entry in the cached document to an apraiser. - */ - private void scanDocument(Strategy strategy) { - synchronized (cache) { - Iterator itr = cache.values().iterator(); - - while (itr.hasNext()) { - strategy.evaluate((Entry)itr.next()); - } - } // synchronized - } - - /* - * Retrieves or creates a file. - */ - private Entry getFileEntry(String name) - throws IOException { - Entry cEntry = null; - - synchronized (cache) { - cEntry = (Entry)cache.get(name); - - if (cEntry == null) { - // create a new file - ZipEntry zEntry = new ZipEntry(name); - zEntry.setTime(new Date().getTime()); - cEntry = new Entry(zEntry); - - if (!editableStrategy.evaluate(cEntry)) { - throw new IOException( - "cannot create/edit readonly file"); // I18N - } - - cEntry = new ReadWriteEntry(zEntry); - cache.put(cEntry.getName(), cEntry); - isModified = true; - } - } // synchronized - - return cEntry; - } - - /* - * Retrieves or creates a folder. - */ - private Entry getFolderEntry(String name) - throws IOException { - Entry cEntry = null; - - synchronized (cache) { - cEntry = (Entry)cache.get(name); - - if (cEntry == null) { - // create a new folder - ZipEntry zEntry = new ZipEntry(name + SEPARATOR); - zEntry.setMethod(ZipEntry.STORED); - zEntry.setSize(0); - CRC32 crc = new CRC32(); - zEntry.setCrc(crc.getValue()); - zEntry.setTime(new Date().getTime()); - cEntry = new Entry(zEntry); - - if (!editableStrategy.evaluate(cEntry)) { - throw new IOException( - "cannot create folder"); // I18N - } - - cEntry = new ReadWriteEntry(zEntry); - cEntry.getOutputStream(); // sets up modified flag - cache.put(cEntry.getName(), cEntry); - isModified = true; - } else { - if (!cEntry.isFolder()) - cEntry = null; - } - } // synchronized - - return cEntry; - } - - /* - * Converts the name to ZIP file name. - * Removes the leading file separator if there is one. - * This is WORKAROUND of the BUG in AbstractFileObject: - * While AbstractFileObject reprecents the root of the filesystem it uses - * the absolute path (the path starts with '/'). It is inconsistent with - * the rest of the code. - * WORKAROUND: we have to strip leading '/' if it is in the name. - */ - private static String zipName(String name) { - String zname = ((name.startsWith(File.separator)) ? - name.substring(File.separator.length()) : name); - - switch (osType) { - case OS_MACOS: - zname = zname.replace(':', '/'); // ':' by '/' - break; - - case OS_WINDOWS: - zname = zname.replace((char)0x5c, '/'); // '\' by '/' - break; - - default: - break; - } - - return zname; - } - - // ----------- IMPLEMENTATIONS OF ABSTRACT FUNCTIONALITY ---------- - - /* ----------------------------------------------------------- - * Information about files and operations on the contents which do - * not affect the file's presence or name. - */ - private class InfoImpl - implements Info { - public boolean folder(String name) { - synchronized (cache) { - String zname = zipName(name); - Entry entry = (Entry)cache.get(zname); - - if (entry != null) - return entry.isFolder(); - - // logical zip file entry - childrenStrategy.setParent(zname); - scanDocument(childrenStrategy); - return (childrenStrategy.countChildren() > 0); - } - } - - public Date lastModified(String name) { - synchronized (cache) { - Entry entry = (Entry)cache.get(zipName(name)); - return new Date((entry != null) ? entry.getTime() : 0L); - } - } - - public boolean readOnly(String name) { - synchronized (cache) { - Entry entry = (Entry)cache.get(zipName(name)); - return entry && entry.isReadOnly(); - } - } - - public String mimeType(String name) { - // Unless you have some special means of determining MIME type - // (e.g. HTTP headers), ask IDE to use its normal heuristics: - // the MIME resolver pool and then file extensions, or if nothing - // matches, just content/unknown. - return null; - } - - public long size(String name) { - synchronized (cache) { - Entry entry = (Entry)cache.get(zipName(name)); - return (entry != null) ? entry.getSize() : 0; - } // synchronized - } - - public InputStream inputStream(String name) - throws FileNotFoundException { - synchronized (cache) { - Entry entry = (Entry)cache.get(zipName(name)); - return (entry != null) ? entry.getInputStream() : null; - } // synchronized - } - - public OutputStream outputStream(String name) - throws IOException { - return getFileEntry(zipName(name)).getOutputStream(); - } - - // AbstractFileSystem handles locking the file to the rest of the IDE. - // This only means that you should define how the file should be locked - // to the outside world--perhaps it does not need to be. - public void lock(String name) - throws IOException { - /* - File file = getFile(name); - if (file.exists() == true && file.canWrite() == false) { - IOException ioe = new IOException("file " + file + - " could not be locked"); - ErrorManager.getDefault().annotate(ioe, NbBundle.getMessage( - OpenOfficeDocFileSystem.class, "EXC_file_could_not_be_locked", - file.getName(), getDisplayName(), file.getPath())); - throw ioe; - } - */ - } - - public void unlock(String name) { - // Nothing special needed to unlock a file to the outside world. - } - - public void markUnimportant(String name) { - // Do nothing special. Version-control systems may use this to mark - // certain files (e.g. *.class) as not needing to be stored in the VCS - // while others (source files) are by default important. - } - - } - - /* ----------------------------------------------------------- - * Operations that change the available files. - */ - private class ChangeImpl - implements Change { - public void createFolder(String name) - throws IOException { - synchronized (cache) { - String zname = zipName(name); - - if (cache.get(zname) != null) { - throw new IOException( - "cannot create new folder: " + name); // I18N - } - - getFolderEntry(zname); - } // synchronized - } - - public void createData(String name) - throws IOException { - synchronized (cache) { - String zname = zipName(name); - - if (cache.get(zname) != null) { - throw new IOException( - "cannot create new data: " + name); // I18N - } - - OutputStream os = getFileEntry(zname).getOutputStream(); - os.close(); - } // synchronized - } - - public void rename(String oldName, String newName) - throws IOException { - String oname = zipName(oldName); - String nname = zipName(newName); - - if ((oname.length() == 0) || (nname.length() == 0)) { - throw new IOException( - "cannot move or rename the root folder"); // I18N - } - - synchronized (cache) { - if (cache.get(nname) != null) { - throw new IOException( - "target file/folder " + newName + " exists"); // I18N - } - - Entry entry = (Entry)cache.get(oname); - - if (entry == null) { - throw new IOException( - "there is no such a file/folder " + oldName); // I18N - } - - if (entry.isReadOnly()) { - throw new IOException( - "file/folder " + oldName + " is readonly"); // I18N - } - - entry.rename(nname); - - if (!editableStrategy.evaluate(entry)) { - entry.rename(oname); - throw new IOException( - "cannot create file/folder"); // I18N - } - - cache.remove(oname); - cache.put(entry.getName(), entry); - } // synchronized - } - - public void delete(String name) - throws IOException { - String zname = zipName(name); - - if (zname.length() == 0) { - throw new IOException( - "cannot delete the root folder"); // I18N - } - - synchronized (cache) { - Entry entry = (Entry)cache.remove(zname); - - if (entry != null) { - // BUG: this is the design bug. Cache has to - // remember that the entry was removed. - isModified = true; - entry.clean(); - } - } // synchronized - } - } - - /* ----------------------------------------------------------- - * Operation which provides the directory structure. - */ - private class ListImpl - implements List { - public String[] children(String name) { - String[] children = null; - - synchronized (cache) { - String zname = zipName(name); - Entry entry = (Entry)cache.get(zname); - - if (entry != null) { - // real zip file entry - if (entry.isFolder()) { - childrenStrategy.setParent(entry.getName()); - } - } else { - // logical zip file entry - // (portion of the path of a real zip file entry) - childrenStrategy.setParent(zname); - } - - scanDocument(childrenStrategy); - children = childrenStrategy.getChildren(); - } // synchronize - - return children; - } - - } - - /** ----------------------------------------------------------- - * This class adds new virtual attribute "java.io.File". - * Because of the fact that FileObjects of __Sample__FileSystem are convertible - * to java.io.File by means of attributes. */ - /*private static class InnerAttrs extends DefaultAttributes { - //static final long serialVersionUID = 1257351369229921993L; - __Sample__FileSystem sfs; - public InnerAttrs(__Sample__FileSystem sfs, AbstractFileSystem.Info info, - AbstractFileSystem.Change change,AbstractFileSystem.List list ) { - super(info, change, list); - this.sfs = sfs; - } - public Object readAttribute(String name, String attrName) { - if (attrName.equals("java.io.File")) // NOI18N - return sfs.getFile(name); - - return super.readAttribute(name, attrName); - } - }*/ - - /* ----------------------------------------------------------- - // Optional special implementations of copy and (cross-directory) move. - private class TransferImpl implements Transfer { - - public boolean copy(String name, Transfer target, String targetName) throws IOException { - // Only permit special implementation within single FS - // (or you could implement it across filesystems if you wished): - if (target != this) return false; - // Specially copy the file in an efficient way, e.g. implement - // a copy-on-write algorithm. - return true; - } - - public boolean move(String name, Transfer target, String targetName) throws IOException { - // Only permit special implementation within single FS - // (or you could implement it across filesystems if you wished): - if (target != this) return false; - // Specially move the file, e.g. retain rename information even - // across directories in a version-control system. - return true; - } - - } - */ - - /* ----------------------------------------------------------- - * This interface hides an action will be performed on an entry. - */ - private interface Strategy { - boolean evaluate(Entry entry); - } - - /* ----------------------------------------------------------- - * Recognizes editable (read-write) entires - */ - private class EditableStrategy - implements Strategy { - private String scope; - - public EditableStrategy(String scope) { - this.scope = scope; - } - - public boolean evaluate(Entry entry) { - // recognizes all entries in a subtree of the - // 'scope' as editable entries - return entry && entry.getName().startsWith(scope); - } - } - - /* ----------------------------------------------------------- - * Recognizes and accumulates immediate children of the parent. - */ - private class ChildrenStrategy - implements Strategy { - private String parent; - private Collection children = new HashSet(); - - public void setParent(String name) { - parent = (name.length() > 0) ? (name + SEPARATOR) : ""; - - if (children == null) - children = (java.util.List)new LinkedList(); - - children.clear(); - } - - public boolean evaluate(Entry entry) { - // do not accept "children" of a file - // ignore "read only" part of the filesystem - if (!entry.isReadOnly()) { - // identify a child - if ((entry.getName().length() > 0) && - (entry.getName().startsWith(parent))) { - // identify an immediate child - String child = entry.getName(); - - if (parent.length() > 0) { - child = entry.getName().substring(parent.length()); - } - - int idx = child.indexOf(SEPARATOR); - - if (idx > 0) // more path elements ahead - child = child.substring(0, idx); - - return children.add(child); - } - } - - return false; - } - - public int countChildren() { - return children.size(); - } - - public String[] getChildren() { - String[] chn = new String[children.size()]; - Iterator itr = children.iterator(); - int idx = 0; - - while (itr.hasNext()) { - chn[idx++] = (String)itr.next(); - } - - return chn; - } - } - - /* ----------------------------------------------------------- - * Recognizes cache entries which have to be save into new archive. - */ - private class ModifiedStrategy - implements Strategy { - private boolean modified; - - public boolean evaluate(Entry entry) { - modified |= entry.isModified(); - return entry.isModified(); - } - - public boolean isModified() { - return modified; - } - } - - /* ----------------------------------------------------------- - * Saves each entry in the filesystem cache. - */ - private class SaveStrategy - implements Strategy { - ZipOutputStream docos; - IOException ioexp; - - public SaveStrategy(File newdoc) - throws IOException { - docos = new ZipOutputStream(new FileOutputStream(newdoc)); - ioexp = null; // success by default - } - - public boolean evaluate(Entry entry) { - if (entry.getName().length() == 0) - return false; - - try { - entry.save(docos); - } catch (IOException ioe) { - if (ioexp == null) - ioexp = ioe; - } - - return true; - } - - public void close() - throws IOException { - if (docos != null) { - try { - docos.close(); - } catch (IOException ioe) { - ioexp = ioe; - } finally { - docos = null; - } - - if (ioexp != null) { - throw ioexp; - } - } - } - } - - /* ----------------------------------------------------------- - * Cleans each entiry in the filesystem cache. - */ - private class CleanStrategy - implements Strategy { - public boolean evaluate(Entry entry) { - try { - entry.clean(); - } catch (java.lang.Exception exp) { - // sorry! can do nothing about it. - } - - return true; - } - } - - /* ----------------------------------------------------------- - * ReadOnly cache entry - */ - private class Entry { - private String name; - private boolean folder; - private long size; - private long time; - private File node; // data files only - - public Entry(ZipEntry entry) { - if (entry != null) { - name = entry.getName(); - folder = entry.isDirectory(); - size = entry.getSize(); - time = entry.getTime(); - - // removes tail file separator from a folder name - if (folder && name.endsWith(SEPARATOR)) { - name = name.substring( - 0, name.length() - SEPARATOR.length()); - } - } else { - // 'null' is special cace of root folder - name = ""; - folder = true; - size = 0; - time = -1; - } - } - - public boolean isReadOnly() { - return true; - } - - public boolean isFolder() { - return folder; - } - - public boolean isModified() { - return false; - } - - public String getName() { - return name; - } - - public long getSize() { - return size; - } - - public long getTime() { - // adjust last modified time to the java.io.File - return (time >= 0) ? time : 0; - } - - public InputStream getInputStream() - throws FileNotFoundException { - return !isFolder() ? new FileInputStream(getFile()) : null; - } - - public OutputStream getOutputStream() - throws IOException { - return null; - } - - public void rename(String name) - throws IOException { - // BUG: this is the design bug. Cache has to manage such kind - // of operation in order to keep the data integrity. - this.name = name; - } - - public void save(ZipOutputStream arch) - throws IOException { - InputStream is = null; - ZipEntry entry = new ZipEntry( - getName() + ((isFolder()) ? SEPARATOR : "")); - - try { - if (isFolder()) { - // folder - entry.setMethod(ZipEntry.STORED); - entry.setSize(0); - CRC32 crc = new CRC32(); - entry.setCrc(crc.getValue()); - entry.setTime(getTime()); - arch.putNextEntry(entry); - } else { - // file - if (!isModified()) - entry.setTime(getTime()); - else - entry.setTime(node.lastModified()); - - arch.putNextEntry(entry); - is = getInputStream(); - FileUtil.copy(is, arch); - } - } finally { - // close streams - if (is != null) { - try { - is.close(); - } catch (java.io.IOException ioe) { - // sorry! can do nothing about it. - } - } - - if (arch != null) - arch.closeEntry(); - } - } - - public void clean() - throws IOException { - if (node != null) - node.delete(); - } - - public String toString() { - return ( - ((isReadOnly()) ? "RO " : "RW ") + - ((isFolder()) ? "D" : "F") + - " \"" + getName() + "\""); - } - - /* package */ File getFile() - throws FileNotFoundException { - if (node == null) { - try { - node = File.createTempFile(TMP_FILE_PREF, TMP_FILE_SUFX); - // copy the file from archive to the cache - OutputStream nos = null; - InputStream zis = null; - - try { - ZipEntry entry = zipFile.getEntry(getName()); - - if (entry != null) { - // copy existing file to the cache - zis = zipFile.getInputStream(entry); - nos = new FileOutputStream(node); - FileUtil.copy(zis, nos); - } - } finally { - // close streams - if (nos != null) { - try { - nos.close(); - } catch (java.io.IOException ioe) { - } - } - - if (zis != null) { - try { - zis.close(); - } catch (java.io.IOException ioe) { - } - } - } - } catch (java.lang.Exception exp) { - // delete cache file - if (node != null) - node.delete(); - - node = null; - throw new FileNotFoundException( - "cannot access file: " + getName()); // I18N - } - } - - return node; - } - - } - - /* ----------------------------------------------------------- - * ReadWrite cache entry - */ - private class ReadWriteEntry - extends Entry { - private boolean modified; - - // 'null' is special cace of root folder - public ReadWriteEntry(ZipEntry entry) { - super(entry); - } - - public boolean isReadOnly() { - return false; - } - - public boolean isModified() { - return modified; - } - - public void rename(String name) - throws IOException { - modified = true; - super.rename(name); - } - - public OutputStream getOutputStream() - throws IOException { - modified = true; - return !isFolder() ? new FileOutputStream(getFile()) : null; - } - } -} |