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.plugin.opennap.util;
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  import org.xnap.plugin.opennap.net.OpenNapDownloadContainerData;
36  import org.xnap.plugin.opennap.net.OpenNapResumeRepository;
37  import org.xnap.util.FileHelper;
38  
39  /***
40   * Provides a binary repository that stores {@link File} objects. This
41   * class can be used to store download files that need to be resumed
42   * later.
43   * 
44   * <p>This class is mostly thread safe (except for {@link #iterator()}).
45   */
46  public class OpenNapBinaryResumeRepository {
47  
48      //--- Constant(s) ---
49  
50  	public static final String FILENAME
51  		= FileHelper.getHomeDir() + "opennap_resumes";
52      
53      //--- Data Field(s) ---
54  
55      private static Logger logger = Logger.getLogger(OpenNapResumeRepository.class);
56  
57      private List list = new LinkedList();
58  
59      //--- Constructor(s) ---
60      
61      public OpenNapBinaryResumeRepository()
62      {
63      }
64  
65      //--- Method(s) ---
66  
67      /***
68       * Adds <code>file</code> to the repository.
69       */
70      public synchronized void add(OpenNapDownloadContainerData data)
71      {
72  		list.add(data);
73      }
74  
75      /***
76       * Returns an iterator over all items in the repository.
77       */
78      public Iterator iterator()
79      {
80  		return list.iterator();
81      }
82  
83      /***
84       * Reads {@link File} objects from <code>filename</code> and adds them
85       * to the repository.
86       *
87       * @param filename the name of the repository file
88       * @param fallbackPath if a file in the repository does not exist,
89       *                     it is looked up in this path
90       * @return true, if all {@link File} objects were read successfully or
91       *         repository did not exist; false, otherwise
92       * @see #add(File)
93       */
94      public boolean read() throws IOException
95      {
96  		logger.debug("reading " + FILENAME);
97  
98  		File file = new File(FILENAME);
99  		if (!file.exists()) {
100 			return true;
101 		}
102 
103 		boolean success = true;
104 		ObjectInputStream in 
105 			= new ObjectInputStream(new FileInputStream(file));
106 		try {
107 			int size = in.readInt();
108 			for (int i = 0; i < size; i++) {
109 				try {
110 					Object o = in.readObject();
111 					if (o != null && o instanceof OpenNapDownloadContainerData) {
112 						add((OpenNapDownloadContainerData)o);
113 					}
114 				}
115 				catch (IOException e) {
116 					throw e;
117 				}
118 				catch (Exception e) {
119 					logger.error("error reading repository at item " 
120 								 + i + "/" + size, e);
121 					success = false;
122 				}
123 			} 
124 		}
125 		finally {
126 			try {
127 				in.close();
128 			}
129 			catch (IOException e) {
130 			}
131 		}
132 		
133         return success;
134     }
135 
136     /***
137      * Removes <code>file</code> from the repository.
138      */
139     public synchronized void remove(OpenNapDownloadContainerData data)
140     {
141 		list.remove(data);
142     }
143 
144     /***
145      * Writes repository content to <code>filename</code>.
146      */
147     public void write(String filename) throws IOException
148     {
149 		logger.debug("writing " + filename);
150 
151 		ObjectOutputStream out 
152 			= new ObjectOutputStream(new FileOutputStream(filename));
153 
154 		try {
155 			out.writeInt(list.size());
156 		
157 			for (Iterator i = list.iterator(); i.hasNext();) {
158 				out.writeObject(i.next());
159 			}
160 		}
161 		finally {
162 			try {
163 				out.close();
164 			}
165 			catch (IOException e) {
166 			}
167 		}
168 	}
169 
170 }