| 1 | |
package org.webslinger.commons.vfs.cow; |
| 2 | |
|
| 3 | |
import java.io.IOException; |
| 4 | |
import java.util.Arrays; |
| 5 | |
import java.util.Collection; |
| 6 | |
import java.util.Collections; |
| 7 | |
import java.util.Iterator; |
| 8 | |
import java.util.LinkedHashSet; |
| 9 | |
import java.util.Set; |
| 10 | |
|
| 11 | |
import org.apache.commons.vfs.FileObject; |
| 12 | |
import org.apache.commons.vfs.FileSystemException; |
| 13 | |
|
| 14 | |
import org.webslinger.commons.vfs.VFSUtil; |
| 15 | |
|
| 16 | |
public class COWEntryImpl implements COWEntry { |
| 17 | |
private final COWState state; |
| 18 | |
private String name; |
| 19 | |
private boolean deleted; |
| 20 | |
private String symlink; |
| 21 | |
private String[] bases; |
| 22 | |
private COWFileObject[] baseFiles; |
| 23 | |
|
| 24 | 109 | COWEntryImpl(COWState state, String name) { |
| 25 | 109 | this.state = state; |
| 26 | 109 | this.name = name; |
| 27 | 109 | bases = new String[0]; |
| 28 | 109 | } |
| 29 | |
|
| 30 | |
synchronized void absorb(boolean deleted, String symlink, Collection<String> bases) { |
| 31 | 13 | this.deleted = deleted; |
| 32 | 13 | this.symlink = symlink; |
| 33 | 13 | LinkedHashSet<String> tmpBases = new LinkedHashSet<String>(bases); |
| 34 | 13 | this.bases = tmpBases.toArray(new String[tmpBases.size()]); |
| 35 | 13 | } |
| 36 | |
|
| 37 | |
public String getName() { |
| 38 | 0 | return name; |
| 39 | |
} |
| 40 | |
|
| 41 | |
public synchronized boolean isDeleted() { |
| 42 | 893 | return deleted; |
| 43 | |
} |
| 44 | |
|
| 45 | |
public synchronized void clear() throws FileSystemException { |
| 46 | 6 | deleted = false; |
| 47 | 6 | symlink = null; |
| 48 | 6 | bases = new String[0]; |
| 49 | 6 | baseFiles = null; |
| 50 | 6 | onChange(); |
| 51 | 6 | } |
| 52 | |
|
| 53 | |
public synchronized boolean isEmpty() { |
| 54 | 322 | return !deleted && symlink == null && bases.length == 0; |
| 55 | |
} |
| 56 | |
|
| 57 | |
public synchronized boolean setDeleted(boolean deleted) throws FileSystemException { |
| 58 | 60 | if (deleted) { |
| 59 | 11 | if (this.deleted) return false; |
| 60 | 11 | this.deleted = true; |
| 61 | 11 | symlink = null; |
| 62 | |
} else { |
| 63 | 49 | if (!this.deleted) return false; |
| 64 | 9 | this.deleted = false; |
| 65 | |
} |
| 66 | 20 | baseFiles = null; |
| 67 | 20 | onChange(); |
| 68 | 20 | return true; |
| 69 | |
} |
| 70 | |
|
| 71 | |
public synchronized String getSymlink() { |
| 72 | 1031 | return symlink; |
| 73 | |
} |
| 74 | |
|
| 75 | |
public synchronized boolean setSymlink(String symlink) throws FileSystemException { |
| 76 | 7 | if (symlink != null && symlink.length() == 0) symlink = null; |
| 77 | 7 | if (symlink == null) { |
| 78 | 1 | if (this.symlink == null) return false; |
| 79 | 1 | this.symlink = null; |
| 80 | |
} else { |
| 81 | 6 | if (symlink.equals(this.symlink)) return false; |
| 82 | 6 | this.symlink = symlink; |
| 83 | |
} |
| 84 | 7 | baseFiles = null; |
| 85 | 7 | onChange(); |
| 86 | 7 | return true; |
| 87 | |
} |
| 88 | |
|
| 89 | |
public synchronized Collection<String> getBases() { |
| 90 | 93 | return Arrays.asList(bases); |
| 91 | |
} |
| 92 | |
|
| 93 | |
public synchronized Collection<COWFileObject> getBaseFiles() throws FileSystemException { |
| 94 | 861 | synchronized (this) { |
| 95 | 861 | if (baseFiles != null) return Arrays.asList(baseFiles); |
| 96 | 103 | COWFileObject dir = state.getDir(); |
| 97 | 103 | COWFileObject[] baseFiles = new COWFileObject[bases.length]; |
| 98 | 127 | for (int i = 0; i < bases.length; i++) { |
| 99 | 24 | baseFiles[i] = dir.resolveFile(bases[i]); |
| 100 | |
} |
| 101 | 103 | this.baseFiles = baseFiles; |
| 102 | 103 | return Arrays.asList(baseFiles); |
| 103 | 0 | } |
| 104 | |
} |
| 105 | |
|
| 106 | |
public synchronized boolean addBase(String base) throws FileSystemException { |
| 107 | 14 | LinkedHashSet<String> tmpBases = new LinkedHashSet<String>(Arrays.asList(bases)); |
| 108 | 14 | if (!tmpBases.add(base)) return false; |
| 109 | 14 | this.bases = tmpBases.toArray(new String[tmpBases.size()]); |
| 110 | 14 | baseFiles = null; |
| 111 | 14 | onChange(); |
| 112 | 14 | return true; |
| 113 | |
} |
| 114 | |
|
| 115 | |
public synchronized boolean removeBase(String base) throws FileSystemException { |
| 116 | 6 | LinkedHashSet<String> tmpBases = new LinkedHashSet<String>(Arrays.asList(bases)); |
| 117 | 6 | if (!tmpBases.remove(base)) return false; |
| 118 | 6 | this.bases = tmpBases.toArray(new String[tmpBases.size()]); |
| 119 | 6 | baseFiles = null; |
| 120 | 6 | onChange(); |
| 121 | 6 | return true; |
| 122 | |
} |
| 123 | |
|
| 124 | |
protected void onChange() throws FileSystemException { |
| 125 | 53 | state.save(); |
| 126 | 53 | if (state.getCOWFileSystem() != null) state.getCOWFileSystem().newGeneration(); |
| 127 | |
|
| 128 | 53 | } |
| 129 | |
|
| 130 | |
public synchronized String toString() { |
| 131 | 0 | StringBuilder sb = new StringBuilder(); |
| 132 | 0 | sb.append('(').append(name); |
| 133 | 0 | if (deleted) sb.append(", deleted"); |
| 134 | 0 | if (symlink != null) sb.append(", symlink[").append(symlink).append(']'); |
| 135 | 0 | sb.append(", bases").append(bases).append(')'); |
| 136 | 0 | return sb.toString(); |
| 137 | |
} |
| 138 | |
|
| 139 | |
public int getSerial() { |
| 140 | 882 | return state.getSerial(); |
| 141 | |
} |
| 142 | |
|
| 143 | |
public boolean checkSerial(int serial) throws FileSystemException { |
| 144 | |
try { |
| 145 | 3437 | return state.checkSerial(serial); |
| 146 | 0 | } catch (IOException e) { |
| 147 | 0 | throw VFSUtil.makeFileSystemException(e); |
| 148 | |
} |
| 149 | |
} |
| 150 | |
} |