1 | package org.greenstone.gsdl3.gs3build.util;
|
---|
2 |
|
---|
3 | import java.net.*;
|
---|
4 | import java.util.*;
|
---|
5 |
|
---|
6 | class HTMLLoadManager implements Runnable
|
---|
7 | { Vector toLoad;
|
---|
8 | Vector loading;
|
---|
9 | Vector loaded;
|
---|
10 | boolean stopFlag;
|
---|
11 | boolean started;
|
---|
12 | Thread thread;
|
---|
13 | static int running;
|
---|
14 |
|
---|
15 | static
|
---|
16 | { running = 0;
|
---|
17 | }
|
---|
18 |
|
---|
19 | /**
|
---|
20 | * Vanilla constructor of an object to load HTML documents in the background
|
---|
21 | */
|
---|
22 | public HTMLLoadManager()
|
---|
23 | { this.toLoad = new Vector();
|
---|
24 | this.loading = new Vector();
|
---|
25 | this.loaded = new Vector();
|
---|
26 | this.thread = null;
|
---|
27 | this.stopFlag = false;
|
---|
28 | this.started = false;
|
---|
29 | }
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * Check if a given document is loading
|
---|
33 | *
|
---|
34 | * @return <code>boolean</code> whether the document is loading or not
|
---|
35 | */
|
---|
36 | public boolean isLoading(String docURL)
|
---|
37 | { int i;
|
---|
38 |
|
---|
39 | for (i = 0; i < this.toLoad.size(); i ++)
|
---|
40 | { if (this.toLoad.elementAt(i).toString().equals(docURL))
|
---|
41 | { return true;
|
---|
42 | }
|
---|
43 | }
|
---|
44 |
|
---|
45 | for (i = 0; i < this.loading.size(); i ++)
|
---|
46 | { if (((HTMLDoc) this.loading.elementAt(i)).urlString().equals(docURL))
|
---|
47 | { return true;
|
---|
48 | }
|
---|
49 | }
|
---|
50 |
|
---|
51 | for (i = 0; i < this.loaded.size(); i ++)
|
---|
52 | { if (((HTMLDoc) this.loaded.elementAt(i)).urlString().equals(docURL))
|
---|
53 | { return true;
|
---|
54 | }
|
---|
55 | }
|
---|
56 | return false;
|
---|
57 | }
|
---|
58 |
|
---|
59 | /**
|
---|
60 | * Start this object as a thread
|
---|
61 | */
|
---|
62 | public synchronized void start()
|
---|
63 | { if (this.thread == null)
|
---|
64 | { this.thread = new Thread(this);
|
---|
65 | this.thread.start(); // start the thread
|
---|
66 | this.stopFlag = false; // reset the stop flag as it could have been reset
|
---|
67 | this.started = true; // note that we're running
|
---|
68 | running ++;
|
---|
69 | }
|
---|
70 | }
|
---|
71 |
|
---|
72 | /**
|
---|
73 | * The main thread function; it calls a number of private service functions to
|
---|
74 | * achieve it's affect. Once the stop flag is set, it runs until all loading
|
---|
75 | * documents are loaded, then stops.
|
---|
76 | */
|
---|
77 | public void run()
|
---|
78 | { int i;
|
---|
79 |
|
---|
80 | while (this.stopFlag == false || this.loading.size() > 0)
|
---|
81 | { // slumber while there's nothing to do
|
---|
82 | while (this.toLoad.size() == 0 && this.loading.size() == 0)
|
---|
83 | { try
|
---|
84 | {
|
---|
85 | thread.sleep(100);
|
---|
86 | }
|
---|
87 | catch (InterruptedException ex)
|
---|
88 | {
|
---|
89 | }
|
---|
90 | }
|
---|
91 |
|
---|
92 | // first check for finished documents
|
---|
93 | i = 0;
|
---|
94 | while (i < this.loading.size())
|
---|
95 | { HTMLDoc doc = (HTMLDoc) this.loading.elementAt(i);
|
---|
96 |
|
---|
97 | if (doc.ready())
|
---|
98 | { this.deschedule(i);
|
---|
99 | }
|
---|
100 | else
|
---|
101 | { i ++;
|
---|
102 | }
|
---|
103 | }
|
---|
104 |
|
---|
105 | // then check for a document to load
|
---|
106 | while (this.stopFlag == false &&
|
---|
107 | this.toLoad.size() > 0 &&
|
---|
108 | this.loading.size() < 10)
|
---|
109 | { this.scheduleNext();
|
---|
110 | }
|
---|
111 | }
|
---|
112 | this.started = false;
|
---|
113 | running --;
|
---|
114 | }
|
---|
115 |
|
---|
116 | /**
|
---|
117 | * Returns the total number of loader managers running at this time
|
---|
118 | *
|
---|
119 | * @return <code>int</code> the number of managers running.
|
---|
120 | */
|
---|
121 | public synchronized int running()
|
---|
122 | { return running;
|
---|
123 | }
|
---|
124 |
|
---|
125 | private synchronized void scheduleNext()
|
---|
126 | { // pop url from list to load
|
---|
127 | URL docURL = (URL) this.toLoad.elementAt(0);
|
---|
128 | this.toLoad.removeElementAt(0);
|
---|
129 |
|
---|
130 | // generate new document and add it to the "loading" vector;
|
---|
131 | // the document content is loaded in another thread
|
---|
132 | HTMLDoc doc = new HTMLDoc(docURL, 1);
|
---|
133 | this.loading.addElement(doc);
|
---|
134 | }
|
---|
135 |
|
---|
136 | private synchronized void deschedule(int i)
|
---|
137 | { // get the document and place it in the loaded list
|
---|
138 | HTMLDoc doc = (HTMLDoc) this.loading.elementAt(i);
|
---|
139 | this.loaded.addElement(doc);
|
---|
140 |
|
---|
141 | // remove it from the loading list
|
---|
142 | this.loading.removeElementAt(i);
|
---|
143 | }
|
---|
144 |
|
---|
145 | /**
|
---|
146 | * Get a loaded document, not blocking if nothing is ready yet.
|
---|
147 | *
|
---|
148 | * @return <code>HTMLDoc</code> the document; NB. this may be <code>null</code> as
|
---|
149 | * it is not guaranteed that there is currently a loaded
|
---|
150 | * document.
|
---|
151 | */
|
---|
152 | public synchronized HTMLDoc nextLoaded()
|
---|
153 | { HTMLDoc reply;
|
---|
154 |
|
---|
155 | // if nothing is loaded, return null
|
---|
156 | if (this.loaded.size() == 0)
|
---|
157 | { return null;
|
---|
158 | }
|
---|
159 |
|
---|
160 | // get the first element from the loaded vector and return it,
|
---|
161 | // removing it from the vector in the meantime
|
---|
162 | reply = (HTMLDoc) this.loaded.elementAt(0);
|
---|
163 | this.loaded.removeElementAt(0);
|
---|
164 | return reply;
|
---|
165 | }
|
---|
166 |
|
---|
167 | /**
|
---|
168 | * Request the loading of a document; this does not block but schedules
|
---|
169 | * the document for loading.
|
---|
170 | *
|
---|
171 | * @param <code>URL</code> the URL of the document to load
|
---|
172 | */
|
---|
173 | public synchronized void load(URL docURL)
|
---|
174 | { // check if it's being loaded already; if so do nothing
|
---|
175 | if (this.isLoading(docURL.toString()) == false)
|
---|
176 | { this.toLoad.addElement(docURL);
|
---|
177 |
|
---|
178 | // self-start if the loading thread isn't running
|
---|
179 | if (this.started == false)
|
---|
180 | { this.start();
|
---|
181 | }
|
---|
182 | }
|
---|
183 | }
|
---|
184 |
|
---|
185 | /**
|
---|
186 | * Get the total number of documents loading/loaded through this loader
|
---|
187 | *
|
---|
188 | * @param <code>int</code> the number of documents
|
---|
189 | */
|
---|
190 | public synchronized int loadingDocs()
|
---|
191 | { return this.toLoad.size() + this.loading.size() + this.loaded.size();
|
---|
192 | }
|
---|
193 |
|
---|
194 | /**
|
---|
195 | * Instruct the manager to stop loading documents
|
---|
196 | */
|
---|
197 | public synchronized void stopLoading()
|
---|
198 | { this.stopFlag = true;
|
---|
199 | }
|
---|
200 |
|
---|
201 | protected void finalize() throws Throwable
|
---|
202 | { this.thread = null;
|
---|
203 | this.loading = null;
|
---|
204 | this.toLoad = null;
|
---|
205 | this.loaded = null;
|
---|
206 | super.finalize();
|
---|
207 | }
|
---|
208 | } |
---|