Source code: com/dghda/module/ModulePathDirComponent.java
1 /* Copyright (C) 2001 Duane Griffin <duanegriffin@users.sourceforge.net>
2 This file is part of Kent.
3
4 Kent is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 Kent is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public
15 License along with Kent; see the file COPYING. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18 */
19
20 package com.dghda.module;
21
22 import java.io.*;
23 import java.util.*;
24
25 /**
26 A module path directory component provides access to module providers in a directory.
27 */
28 public class ModulePathDirComponent implements ModulePathComponent {
29
30 /** An iterator over the contents of the directory. */
31 protected class DirIterator implements Iterator {
32
33 /**
34 Create a new iterator.
35 @param updated True if only entries that are new or have been modified since the last scan are included.
36 */
37 public DirIterator (boolean updated, long lastScanned) {
38
39 // List all class files in the directory
40 m_Index = 0;
41 m_Entries = m_File.list (new FilenameFilter() {
42 public boolean accept (File dir, String name) {
43 return name.endsWith (".class");
44 }
45 });
46
47 m_Updated = updated;
48 m_LastScanned = lastScanned;
49 m_Current = getNextEntry();
50 }
51
52 /** Returns true if there is another provider available. */
53 public boolean hasNext() {
54 return (m_Current != null);
55 }
56
57 /** Returns the next provider. */
58 public Object next() {
59
60 // Check we haven't gone past the last entry
61 if (m_Current == null)
62 throw new NoSuchElementException();
63
64 // Move on
65 ModulePathFileComponent entry = m_Current;
66 m_Current = getNextEntry();
67
68 // Get the provider
69 return entry.getProvider();
70 }
71
72 /** Throws a UnsupportedOperationException exception. */
73 public void remove() {
74 throw new UnsupportedOperationException();
75 }
76
77 private ModulePathFileComponent getNextEntry() {
78 ModulePathFileComponent result = null;
79
80 // Grab the next entry
81 while (m_Index != m_Entries.length) {
82 File candidate = new File (m_File, m_Entries[m_Index++]);
83
84 // Ignore special files
85 if (!candidate.isFile())
86 continue;
87
88 // Get the file's component
89 ModulePathFileComponent entry = getComponent (candidate.getName());
90
91 // Check last scan time, if required
92 if (m_Updated && m_LastScanned > entry.getProvider().getModified())
93 continue;
94
95 // OK, use it
96 result = entry;
97 break;
98 }
99
100 return result;
101 }
102
103 private int m_Index = 0;
104 private String [] m_Entries;
105 private boolean m_Updated;
106 private long m_LastScanned;
107 private ModulePathFileComponent m_Current;
108 }
109
110 /** Create a new path component representing the specified directory. */
111 public ModulePathDirComponent (String dir) throws InvalidPathException {
112 m_File = new File (dir);
113
114 // Check the path is a directory
115 if (!m_File.isDirectory())
116 throw new InvalidPathException ("Not a directory", dir);
117 }
118
119 /**
120 Iterate over all providers in the directory.
121 @param updated If true only new providers or ones which have been modified since the last scan will be returned.
122 */
123 public Iterator getProviders (boolean updated) {
124
125 // Check whether we should bother scanning the directory
126 if (updated && (m_Scanned >= m_File.lastModified())) {
127 return new ModulePathComponent.EmptyIterator();
128 } else {
129 long last = m_Scanned;
130 m_Scanned = (new Date()).getTime();
131 return new DirIterator (updated, last);
132 }
133 }
134
135 /** Returns the path to the directory. */
136 public String getPath() {
137 return m_File.getName();
138 }
139
140 /** Return the component representing the given file. */
141 protected synchronized ModulePathFileComponent getComponent (String file) {
142 ModulePathFileComponent result = (ModulePathFileComponent) m_FileComponents.get (file);
143 if (result == null) {
144 result = new ModulePathFileComponent (m_File.getPath() + File.separator + file);
145 m_FileComponents.put (file, result);
146 }
147 return result;
148 }
149
150 private File m_File;
151 private long m_Scanned = 0;
152 private TreeMap m_FileComponents = new TreeMap();
153 }