1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.io;
21
22
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.ObjectInputStream;
29 import java.io.ObjectOutputStream;
30 import java.util.Iterator;
31 import java.util.LinkedList;
32 import java.util.List;
33
34 import org.apache.log4j.Logger;
35
36 /***
37 * Provides a binary repository that stores {@link File} objects. This
38 * class can be used to store download files that need to be resumed
39 * later.
40 *
41 * <p>This class is mostly thread safe (except for {@link #iterator()}).
42 */
43 public class ResumeRepository {
44
45
46
47
48
49 private static Logger logger = Logger.getLogger(ResumeRepository.class);
50
51 private List list = new LinkedList();
52
53
54
55 public ResumeRepository()
56 {
57 }
58
59
60
61 /***
62 * Adds <code>file</code> to the repository.
63 */
64 public synchronized void add(File file)
65 {
66 list.add(file);
67 }
68
69 /***
70 * Returns an iterator over all items in the repository.
71 */
72 public Iterator iterator()
73 {
74 return list.iterator();
75 }
76
77 /***
78 * Removes <code>file</code> from the repository.
79 */
80 public synchronized void remove(File file)
81 {
82 list.remove(file);
83 }
84
85 /***
86 * Reads {@link File} objects from <code>filename</code> and adds them
87 * to the repository.
88 *
89 * @param filename the name of the repository file
90 * @param fallbackPath if a file in the repository does not exist,
91 * it is looked up in this path
92 * @return true, if all {@link File} objects were read successfully or
93 * repository did not exist; false, otherwise
94 * @see #add(File)
95 */
96 public synchronized boolean read(String filename, String fallbackPath)
97 throws IOException
98 {
99 logger.debug("reading " + filename);
100
101 File file = new File(filename);
102 if (!file.exists()) {
103 return true;
104 }
105
106 ObjectInputStream in
107 = new ObjectInputStream(new FileInputStream(file));
108
109 boolean success = true;
110 int size = in.readInt();
111 for (int i = 0; i < size; i++) {
112 try {
113 Object o = in.readObject();
114 if (o != null && o instanceof File) {
115 File f = (File)o;
116 if (!f.exists()) {
117
118 f = new File(fallbackPath, f.getName());
119 if (!f.exists()) {
120
121 continue;
122 }
123 }
124
125 add(f);
126 }
127 }
128 catch (IOException e) {
129 throw e;
130 }
131 catch (Exception e) {
132 logger.error("error reading repository at item "
133 + i + "/" + size + " ", e);
134 success = false;
135 }
136 }
137
138 return success;
139 }
140
141 /***
142 * Writes repository content to <code>filename</code>.
143 */
144 public synchronized void write(String filename) throws IOException
145 {
146 logger.debug("writing " + filename);
147
148 ObjectOutputStream out
149 = new ObjectOutputStream(new FileOutputStream(filename));
150
151 out.writeInt(list.size());
152
153 for (Iterator i = list.iterator(); i.hasNext();) {
154 out.writeObject(i.next());
155 }
156
157 out.flush();
158 out.close();
159 }
160
161 }
162