root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / com / izforge / izpack / panels / PacksModel.java @ 15280
History | View | Annotate | Download (9.28 KB)
1 |
/*
|
---|---|
2 |
* $Id: PacksModel.java,v 1.1 2006/06/14 07:29:07 cesar Exp $
|
3 |
* IzPack
|
4 |
* Copyright (C) 2001-2004 Julien Ponge
|
5 |
*
|
6 |
* File : PacksModel.java
|
7 |
* Description : A table model for packs.
|
8 |
* Author's email : julien@izforge.com
|
9 |
* Author's Website : http://www.izforge.com
|
10 |
*
|
11 |
* Portions are Copyright (C) 2002 Marcus Wolschon
|
12 |
* Portions are Copyright (C) 2002 Jan Blok (jblok@profdata.nl - PDM - www.profdata.nl)
|
13 |
* Portions are Copyright (C) 2004 Gaganis Giorgos (gaganis@users.berlios.de)
|
14 |
*
|
15 |
* This program is free software; you can redistribute it and/or
|
16 |
* modify it under the terms of the GNU General Public License
|
17 |
* as published by the Free Software Foundation; either version 2
|
18 |
* of the License, or any later version.
|
19 |
*
|
20 |
* This program is distributed in the hope that it will be useful,
|
21 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
22 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
23 |
* GNU General Public License for more details.
|
24 |
*
|
25 |
* You should have received a copy of the GNU General Public License
|
26 |
* along with this program; if not, write to the Free Software
|
27 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
28 |
*/
|
29 |
package com.izforge.izpack.panels; |
30 |
|
31 |
import com.izforge.izpack.Pack; |
32 |
import com.izforge.izpack.LocaleDatabase; |
33 |
|
34 |
import javax.swing.table.AbstractTableModel; |
35 |
import java.util.List; |
36 |
import java.util.Map; |
37 |
import java.util.HashMap; |
38 |
|
39 |
/**
|
40 |
* User: Gaganis Giorgos
|
41 |
* Date: Sep 17, 2004
|
42 |
* Time: 8:33:21 AM
|
43 |
*/
|
44 |
class PacksModel extends AbstractTableModel |
45 |
{ |
46 |
private List packs; |
47 |
private List packsToInstall; |
48 |
private PacksPanelInterface panel;
|
49 |
private LocaleDatabase langpack;
|
50 |
//This is used to represent the status of the checkbox
|
51 |
private int[] checkValues; |
52 |
//Map to hold the object name relationship
|
53 |
Map namesObj;
|
54 |
//Map to hold the object name relationship
|
55 |
Map namesPos;
|
56 |
|
57 |
public PacksModel(List packs, List packsToInstall,PacksPanelInterface panel) |
58 |
{ |
59 |
|
60 |
this.packs = packs;
|
61 |
this.packsToInstall = packsToInstall;
|
62 |
this.panel = panel;
|
63 |
langpack = panel.getLangpack(); |
64 |
checkValues = new int[packs.size()]; |
65 |
reverseDeps(); |
66 |
initvalues(); |
67 |
} |
68 |
/**
|
69 |
* Creates the reverse dependency graph
|
70 |
*/
|
71 |
private void reverseDeps() |
72 |
{ |
73 |
//name to pack map
|
74 |
namesObj = new HashMap(); |
75 |
for (int i = 0; i < packs.size(); i++) |
76 |
{ |
77 |
Pack pack = (Pack) packs.get(i); |
78 |
namesObj.put(pack.name,pack); |
79 |
} |
80 |
//process each pack
|
81 |
for (int i = 0; i < packs.size(); i++) |
82 |
{ |
83 |
Pack pack = (Pack) packs.get(i); |
84 |
List deps = pack.dependencies;
|
85 |
for (int j = 0; deps != null && j < deps.size(); j++) |
86 |
{ |
87 |
String name = (String) deps.get(j); |
88 |
Pack parent = (Pack) namesObj.get(name); |
89 |
parent.addRevDep(pack.name); |
90 |
} |
91 |
} |
92 |
|
93 |
} |
94 |
private void initvalues() |
95 |
{ |
96 |
//name to pack position map
|
97 |
namesPos = new HashMap(); |
98 |
for (int i = 0; i < packs.size(); i++) |
99 |
{ |
100 |
Pack pack = (Pack) packs.get(i); |
101 |
namesPos.put(pack.name,new Integer(i)); |
102 |
} |
103 |
//Init to the first values
|
104 |
for (int i = 0; i < packs.size(); i++) |
105 |
{ |
106 |
Pack pack = (Pack) packs.get(i); |
107 |
if(packsToInstall.contains(pack))
|
108 |
checkValues[i] =1;
|
109 |
} |
110 |
//Check out and disable the ones that are excluded by non fullfiled deps
|
111 |
for (int i = 0; i < packs.size(); i++) |
112 |
{ |
113 |
Pack pack = (Pack) packs.get(i); |
114 |
if(checkValues[i] ==0) |
115 |
{ |
116 |
List deps = pack.revDependencies;
|
117 |
for (int j = 0;deps != null && j < deps.size(); j++) |
118 |
{ |
119 |
String name = (String) deps.get(j); |
120 |
int pos = getPos(name);
|
121 |
checkValues[pos] = -2;
|
122 |
} |
123 |
} |
124 |
} |
125 |
// The required ones must propagate their required status to all the ones
|
126 |
// that they depend on
|
127 |
for (int i = 0; i < packs.size(); i++) |
128 |
{ |
129 |
Pack pack = (Pack) packs.get(i); |
130 |
if(pack.required ==true) |
131 |
propRequirement(pack.name); |
132 |
} |
133 |
} |
134 |
private void propRequirement(String name) |
135 |
{ |
136 |
|
137 |
final int pos = getPos(name); |
138 |
checkValues[pos]=-1;
|
139 |
List deps = ((Pack)packs.get(pos)).dependencies;
|
140 |
for (int i = 0; deps != null && i < deps.size(); i++) |
141 |
{ |
142 |
String s = (String) deps.get(i); |
143 |
propRequirement(s); |
144 |
} |
145 |
|
146 |
|
147 |
} |
148 |
/**
|
149 |
* Given a map of names and Integer for position and a name it return
|
150 |
* the position of this name as an int
|
151 |
*
|
152 |
* @return
|
153 |
*/
|
154 |
private int getPos(String name) |
155 |
{ |
156 |
return ((Integer)namesPos.get(name)).intValue(); |
157 |
} |
158 |
|
159 |
/*
|
160 |
* @see TableModel#getRowCount()
|
161 |
*/
|
162 |
public int getRowCount() |
163 |
{ |
164 |
return packs.size();
|
165 |
} |
166 |
|
167 |
/*
|
168 |
* @see TableModel#getColumnCount()
|
169 |
*/
|
170 |
public int getColumnCount() |
171 |
{ |
172 |
return 3; |
173 |
} |
174 |
|
175 |
/*
|
176 |
* @see TableModel#getColumnClass(int)
|
177 |
*/
|
178 |
public Class getColumnClass(int columnIndex) |
179 |
{ |
180 |
switch (columnIndex)
|
181 |
{ |
182 |
case 0 : |
183 |
return Integer.class; |
184 |
|
185 |
default :
|
186 |
return String.class; |
187 |
} |
188 |
} |
189 |
|
190 |
/*
|
191 |
* @see TableModel#isCellEditable(int, int)
|
192 |
*/
|
193 |
public boolean isCellEditable(int rowIndex, int columnIndex) |
194 |
{ |
195 |
if (checkValues[rowIndex] <0) |
196 |
{ |
197 |
return false; |
198 |
}else if (columnIndex == 0) |
199 |
{ |
200 |
return true; |
201 |
} else
|
202 |
{ |
203 |
return false; |
204 |
} |
205 |
} |
206 |
|
207 |
/*
|
208 |
* @see TableModel#getValueAt(int, int)
|
209 |
*/
|
210 |
public Object getValueAt(int rowIndex, int columnIndex) |
211 |
{ |
212 |
|
213 |
Pack pack = (Pack) packs.get(rowIndex); |
214 |
switch (columnIndex)
|
215 |
{ |
216 |
case 0 : |
217 |
|
218 |
return new Integer(checkValues[rowIndex]); |
219 |
|
220 |
case 1 : |
221 |
|
222 |
if (langpack == null || pack.id == null || pack.id.equals("")){ |
223 |
return pack.name;
|
224 |
}else{
|
225 |
return langpack.getString(pack.id);
|
226 |
} |
227 |
|
228 |
case 2 : |
229 |
return Pack.toByteUnitsString((int) pack.nbytes); |
230 |
|
231 |
default :
|
232 |
return null; |
233 |
} |
234 |
} |
235 |
|
236 |
/*
|
237 |
* @see TableModel#setValueAt(Object, int, int)
|
238 |
*/
|
239 |
public void setValueAt(Object aValue, int rowIndex, int columnIndex) |
240 |
{ |
241 |
if (columnIndex == 0) |
242 |
{ |
243 |
if (aValue instanceof Integer) |
244 |
{ |
245 |
Pack pack = (Pack) packs.get(rowIndex); |
246 |
if (((Integer) aValue).intValue() == 1) |
247 |
{ |
248 |
checkValues[rowIndex] = 1;
|
249 |
updateDeps(); |
250 |
|
251 |
int bytes = panel.getBytes();
|
252 |
bytes += pack.nbytes; |
253 |
panel.setBytes(bytes); |
254 |
} else
|
255 |
{ |
256 |
checkValues[rowIndex] = 0;
|
257 |
updateDeps(); |
258 |
|
259 |
int bytes = panel.getBytes();
|
260 |
bytes -= pack.nbytes; |
261 |
panel.setBytes(bytes); |
262 |
} |
263 |
fireTableDataChanged(); |
264 |
refreshPacksToInstall(); |
265 |
panel.showSpaceRequired(); |
266 |
} |
267 |
} |
268 |
} |
269 |
|
270 |
private void refreshPacksToInstall() |
271 |
{ |
272 |
|
273 |
packsToInstall.clear(); |
274 |
for (int i = 0; i < packs.size(); i++) |
275 |
{ |
276 |
Object pack = packs.get(i);
|
277 |
if(Math.abs(checkValues[i]) == 1) |
278 |
packsToInstall.add(pack); |
279 |
|
280 |
} |
281 |
|
282 |
} |
283 |
/**
|
284 |
* This function updates the checkboxes after a change by disabling packs
|
285 |
* that cannot be installed anymore and enabling those that can after the
|
286 |
* change. This is accomplished by running a search that pinpoints the packs
|
287 |
* that must be disabled by a non-fullfiled dependency.
|
288 |
*/
|
289 |
private void updateDeps() |
290 |
{ |
291 |
int[] statusArray = new int[packs.size()]; |
292 |
for (int i = 0; i < statusArray.length; i++) |
293 |
{ |
294 |
statusArray[i] = 0;
|
295 |
} |
296 |
dfs(statusArray); |
297 |
for (int i = 0; i < statusArray.length; i++) |
298 |
{ |
299 |
if (statusArray[i] ==0 && checkValues[i] <0) |
300 |
checkValues[i] += 2;
|
301 |
if (statusArray[i] ==1 && checkValues[i] >=0) |
302 |
checkValues[i] = -2;
|
303 |
|
304 |
|
305 |
} |
306 |
// The required ones must propagate their required status to all the ones
|
307 |
// that they depend on
|
308 |
for (int i = 0; i < packs.size(); i++) |
309 |
{ |
310 |
Pack pack = (Pack) packs.get(i); |
311 |
if(pack.required ==true) |
312 |
propRequirement(pack.name); |
313 |
} |
314 |
|
315 |
|
316 |
} |
317 |
/** We use a modified dfs graph search algorithm as described in:
|
318 |
* Thomas H. Cormen, Charles Leiserson, Ronald Rivest and Clifford Stein. Introduction
|
319 |
* to algorithms 2nd Edition 540-549,MIT Press, 2001
|
320 |
* @return
|
321 |
*/
|
322 |
private int dfs(int[] status) |
323 |
{ |
324 |
for (int i = 0; i < packs.size(); i++) |
325 |
{ |
326 |
for (int j = 0; j < packs.size(); j++) |
327 |
{ |
328 |
((Pack)packs.get(j)).color = Pack.WHITE; |
329 |
} |
330 |
Pack pack = (Pack) packs.get(i); |
331 |
boolean wipe = false; |
332 |
|
333 |
if(dfsVisit(pack,status,wipe)!=0) |
334 |
return -1; |
335 |
|
336 |
} |
337 |
return 0; |
338 |
} |
339 |
private int dfsVisit(Pack u,int[] status,boolean wipe) |
340 |
{ |
341 |
u.color = Pack.GREY; |
342 |
int check = checkValues[getPos(u.name)];
|
343 |
|
344 |
if(Math.abs(check) !=1) |
345 |
{ |
346 |
wipe = true;
|
347 |
} |
348 |
List deps = u.revDependencies;
|
349 |
if (deps != null) |
350 |
{ |
351 |
for (int i = 0; i < deps.size(); i++) |
352 |
{ |
353 |
String name = (String) deps.get(i); |
354 |
Pack v = (Pack)namesObj.get(name); |
355 |
if(wipe)
|
356 |
{ |
357 |
status[getPos(v.name)] =1;
|
358 |
} |
359 |
if(v.color == Pack.WHITE)
|
360 |
{ |
361 |
|
362 |
final int result = dfsVisit(v,status,wipe); |
363 |
if(result != 0) |
364 |
return result;
|
365 |
} |
366 |
} |
367 |
} |
368 |
u.color = Pack.BLACK; |
369 |
return 0; |
370 |
} |
371 |
} |