View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.io;
21  
22  //import xnap.util.*;
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      //--- Constant(s) ---
46      
47      //--- Data Field(s) ---
48  
49      private static Logger logger = Logger.getLogger(ResumeRepository.class);
50  
51      private List list = new LinkedList();
52  
53      //--- Constructor(s) ---
54      
55      public ResumeRepository()
56      {
57      }
58  
59      //--- Method(s) ---
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 						// check if the file was moved
118 						f = new File(fallbackPath, f.getName());
119 						if (!f.exists()) {
120 							// the file has been deleted
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