1 package twcsckernel.projectbase.io;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.rmi.RemoteException;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.Map;
12
13 import twcsckernel.projectbase.common.WriterFactory;
14
15 public class WriterFactoryImpl implements WriterFactory {
16
17 private Collection<LocalFsChangeListener> fsListeners = null;
18
19 private Map<Integer, FileAndStream> fileAndStreamMap = Collections
20 .synchronizedMap(new HashMap<Integer, FileAndStream>());
21
22 private static final FileNotFoundException fileNotFound = new FileNotFoundException();
23
24 private static final SecurityException illegalAccess = new SecurityException();
25
26 private static final ItemNotFoundException streamNotFound = new ItemNotFoundException();
27
28 private Object idPointerMutex = new Object();
29
30 private int idPointer = 0;
31
32 private FileSecurityManager defaultSecManager = null;
33
34 private static class FileAndStream {
35 public final File file;
36 public final FileOutputStream fStream;
37 public FileAndStream(File file, FileOutputStream stream) {
38 this.file = file;
39 fStream = stream;
40 }
41 }
42
43 public WriterFactoryImpl(FileSecurityManager defaultSecManager,
44 Collection<LocalFsChangeListener> listeners)
45 throws NullPointerException {
46 if (defaultSecManager == null || listeners == null)
47 throw new NullPointerException();
48 this.defaultSecManager = defaultSecManager;
49 fsListeners = listeners;
50 }
51
52 public RemoteFileOutputStream newFileOutputStream(String filePath)
53 throws RemoteException, FileNotFoundException, SecurityException {
54 return newFileOutputStream(filePath, defaultSecManager);
55 }
56
57 public RemoteFileOutputStream newFileOutputStream(String filePath,
58 FileSecurityManager secManager) throws RemoteException,
59 FileNotFoundException, SecurityException {
60
61 File file;
62 try {
63 file = secManager.getUserRootPathManager().getFile(filePath);
64 } catch (IOException e1) {
65 throw new FileNotFoundException();
66 }
67 boolean fileExists = file.exists();
68 switch (defaultSecManager.checkWriteAccess(file)) {
69 case FileSecurityManager.ACC_NOT_FOUND :
70 throw fileNotFound;
71 case FileSecurityManager.ACC_ILLEGAL :
72 throw illegalAccess;
73 }
74
75 RemoteFileOutputStream rfos = null;
76 try {
77 FileOutputStream fos = new FileOutputStream(file);
78 if (!fileExists)
79
80 {
81 FsChangeDescriptor fd = new FsChangeDescriptor(
82 FsChangeDescriptor.FILE_CREATE);
83 fd.setChangeInfo(FileFactoryImpl.getFileDescriptor(file));
84 fireFsListeners(fd);
85 }
86 synchronized (idPointerMutex) {
87 fileAndStreamMap.put(idPointer, new FileAndStream(file, fos));
88 rfos = new RemoteFileOutputStream(idPointer, this);
89 idPointer++;
90 }
91 } catch (FileNotFoundException e) {
92 throw e;
93 }
94 return rfos;
95 }
96
97 public void write(int fileID, int b) throws RemoteException, IOException,
98 ItemNotFoundException {
99 FileOutputStream os = getStream(fileID);
100 synchronized (os) {
101 os.write(b);
102 }
103 }
104
105 public void write(int fileID, byte[] b) throws RemoteException,
106 IOException, ItemNotFoundException {
107 FileOutputStream os = getStream(fileID);
108 synchronized (os) {
109 os.write(b);
110 }
111 }
112
113 public void flush(int fileID) throws RemoteException, IOException,
114 ItemNotFoundException {
115 FileOutputStream os = getStream(fileID);
116 synchronized (os) {
117 os.flush();
118 }
119
120 }
121
122 public void close(int fileID) throws RemoteException, IOException,
123 ItemNotFoundException {
124 FileAndStream fAndS = fileAndStreamMap.get(fileID);
125 if (fAndS == null)
126 throw streamNotFound;
127 close(fAndS);
128 fileAndStreamMap.remove(fileID);
129 }
130 public void releaseAllResources() {
131 Collection<FileAndStream> streams = fileAndStreamMap.values();
132 for (FileAndStream fAndS : streams)
133 try {
134 close(fAndS);
135 } catch (IOException e) {
136 }
137 fileAndStreamMap.clear();
138 }
139
140 private void close(FileAndStream fAndS) throws IOException {
141 synchronized (fAndS.fStream) {
142 fAndS.fStream.close();
143 FsChangeDescriptor fd = new FsChangeDescriptor(
144 FsChangeDescriptor.FILE_REFRESH);
145 fd.setChangeInfo(FileFactoryImpl.getFileDescriptor(fAndS.file));
146 fireFsListeners(fd);
147 }
148 }
149
150 private FileOutputStream getStream(int fileID) throws ItemNotFoundException {
151 FileAndStream fAndS = fileAndStreamMap.get(fileID);
152 if (fAndS == null)
153 throw streamNotFound;
154 return fAndS.fStream;
155 }
156
157 private void fireFsListeners(FsChangeDescriptor desc) {
158 for (LocalFsChangeListener fsL : fsListeners)
159 fsL.fsChangeNotify(desc);
160 }
161
162 }