001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.log4j.lf5.viewer.configure; 018 019import java.io.BufferedInputStream; 020import java.io.File; 021import java.io.FileInputStream; 022import java.io.FileNotFoundException; 023import java.io.FileOutputStream; 024import java.io.IOException; 025import java.io.InputStream; 026import java.io.ObjectInputStream; 027import java.io.ObjectOutputStream; 028import java.net.URL; 029import java.util.Iterator; 030import java.util.LinkedList; 031 032 033/** 034 * <p>MRUFileManager handles the storage and retrival the most 035 * recently opened log files. 036 * 037 * @author Brad Marlborough 038 * @author Richard Hurst 039 */ 040 041// Contributed by ThoughtWorks Inc. 042 043public class MRUFileManager { 044 //-------------------------------------------------------------------------- 045 // Constants: 046 //-------------------------------------------------------------------------- 047 private static final String CONFIG_FILE_NAME = "mru_file_manager"; 048 private static final int DEFAULT_MAX_SIZE = 3; 049 050 //-------------------------------------------------------------------------- 051 // Protected Variables: 052 //-------------------------------------------------------------------------- 053 054 //-------------------------------------------------------------------------- 055 // Private Variables: 056 //-------------------------------------------------------------------------- 057 private int _maxSize = 0; 058 private LinkedList _mruFileList; 059 060 //-------------------------------------------------------------------------- 061 // Constructors: 062 //-------------------------------------------------------------------------- 063 public MRUFileManager() { 064 load(); 065 setMaxSize(DEFAULT_MAX_SIZE); 066 } 067 068 public MRUFileManager(int maxSize) { 069 load(); 070 setMaxSize(maxSize); 071 } 072 //-------------------------------------------------------------------------- 073 // Public Methods: 074 //-------------------------------------------------------------------------- 075 076 /** 077 * Saves a list of MRU files out to a file. 078 */ 079 public void save() { 080 File file = new File(getFilename()); 081 082 try { 083 ObjectOutputStream oos = new ObjectOutputStream(new 084 FileOutputStream(file)); 085 oos.writeObject(_mruFileList); 086 oos.flush(); 087 oos.close(); 088 } catch (Exception e) { 089 // do nothing 090 e.printStackTrace(); 091 } 092 } 093 094 /** 095 * Gets the size of the MRU file list. 096 */ 097 public int size() { 098 return _mruFileList.size(); 099 } 100 101 /** 102 * Returns a particular file name stored in a MRU file 103 * list based on an index value. 104 */ 105 public Object getFile(int index) { 106 if (index < size()) { 107 return _mruFileList.get(index); 108 } 109 110 return null; 111 } 112 113 /** 114 * Returns a input stream to the resource at the specified index 115 */ 116 public InputStream getInputStream(int index) throws IOException, 117 FileNotFoundException { 118 if (index < size()) { 119 Object o = getFile(index); 120 if (o instanceof File) { 121 return getInputStream((File) o); 122 } else { 123 return getInputStream((URL) o); 124 } 125 } 126 return null; 127 } 128 129 /** 130 * Adds a file name to the MRU file list. 131 */ 132 public void set(File file) { 133 setMRU(file); 134 } 135 136 /** 137 * Adds a url to the MRU file list. 138 */ 139 public void set(URL url) { 140 setMRU(url); 141 } 142 143 /** 144 * Gets the list of files stored in the MRU file list. 145 */ 146 public String[] getMRUFileList() { 147 if (size() == 0) { 148 return null; 149 } 150 151 String[] ss = new String[size()]; 152 153 for (int i = 0; i < size(); i++) { 154 Object o = getFile(i); 155 if (o instanceof File) { 156 ss[i] = ((File) o).getAbsolutePath(); 157 } else // must be a url 158 { 159 ss[i] = o.toString(); 160 } 161 162 } 163 164 return ss; 165 } 166 167 /** 168 * Moves the the index to the top of the MRU List 169 * 170 * @param index The index to be first in the mru list 171 */ 172 public void moveToTop(int index) { 173 _mruFileList.add(0, _mruFileList.remove(index)); 174 } 175 176 /** 177 * Creates the directory where the MRU file list will be written. 178 * The "lf5" directory is created in the Documents and Settings 179 * directory on Windows 2000 machines and where ever the user.home 180 * variable points on all other platforms. 181 */ 182 public static void createConfigurationDirectory() { 183 String home = System.getProperty("user.home"); 184 String sep = System.getProperty("file.separator"); 185 File f = new File(home + sep + "lf5"); 186 if (!f.exists()) { 187 try { 188 f.mkdir(); 189 } catch (SecurityException e) { 190 e.printStackTrace(); 191 } 192 } 193 194 } 195 //-------------------------------------------------------------------------- 196 // Protected Methods: 197 //-------------------------------------------------------------------------- 198 /** 199 * Gets an input stream for the corresponding file. 200 * 201 * @param file The file to create the input stream from. 202 * @return InputStream 203 */ 204 protected InputStream getInputStream(File file) throws IOException, 205 FileNotFoundException { 206 BufferedInputStream reader = 207 new BufferedInputStream(new FileInputStream(file)); 208 209 return reader; 210 } 211 212 /** 213 * Gets an input stream for the corresponding URL. 214 * 215 * @param url The url to create the input stream from. 216 * @return InputStream 217 */ 218 protected InputStream getInputStream(URL url) throws IOException { 219 return url.openStream(); 220 } 221 222 /** 223 * Adds an object to the mru. 224 */ 225 protected void setMRU(Object o) { 226 int index = _mruFileList.indexOf(o); 227 228 if (index == -1) { 229 _mruFileList.add(0, o); 230 setMaxSize(_maxSize); 231 } else { 232 moveToTop(index); 233 } 234 } 235 236 /** 237 * Loads the MRU file list in from a file and stores it in a LinkedList. 238 * If no file exists, a new LinkedList is created. 239 */ 240 protected void load() { 241 createConfigurationDirectory(); 242 File file = new File(getFilename()); 243 if (file.exists()) { 244 try { 245 ObjectInputStream ois = new ObjectInputStream( 246 new FileInputStream(file)); 247 _mruFileList = (LinkedList) ois.readObject(); 248 ois.close(); 249 250 // check that only files and url are in linked list 251 Iterator it = _mruFileList.iterator(); 252 while (it.hasNext()) { 253 Object o = it.next(); 254 if (!(o instanceof File) && !(o instanceof URL)) { 255 it.remove(); 256 } 257 } 258 } catch (Exception e) { 259 _mruFileList = new LinkedList(); 260 } 261 } else { 262 _mruFileList = new LinkedList(); 263 } 264 265 } 266 267 protected String getFilename() { 268 String home = System.getProperty("user.home"); 269 String sep = System.getProperty("file.separator"); 270 271 return home + sep + "lf5" + sep + CONFIG_FILE_NAME; 272 } 273 274 /** 275 * Ensures that the MRU list will have a MaxSize. 276 */ 277 protected void setMaxSize(int maxSize) { 278 if (maxSize < _mruFileList.size()) { 279 for (int i = 0; i < _mruFileList.size() - maxSize; i++) { 280 _mruFileList.removeLast(); 281 } 282 } 283 284 _maxSize = maxSize; 285 } 286 //-------------------------------------------------------------------------- 287 // Private Methods: 288 //-------------------------------------------------------------------------- 289 290 //-------------------------------------------------------------------------- 291 // Nested Top-Level Classes or Interfaces 292 //-------------------------------------------------------------------------- 293}