Statistics
| Revision:

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
}