View Javadoc
1 /*** 2 * DependencyModel.java 3 * 4 * Project: Dependency Tool 5 * 6 * WHEN WHO WHAT 7 * 06.06.2003 pko initial public release 8 * 20.01.2003 pko modification 9 * 18.04.2002 ctr modification 10 * 22.01.2002 ctr modification 11 * 08.01.2002 ctr creation 12 * 13 * Copyright 2003 ELCA Informatique SA 14 * Av. de la Harpe 22-24, 1000 Lausanne 13, Switzerland 15 * www.elca.ch 16 * 17 * This library is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU Lesser General Public License 19 * as published by the Free Software Foundation; either version 2.1 of 20 * the License, or (at your option) any later version. 21 * 22 * This library is distributed in the hope that it will be useful, but 23 * WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 25 * Lesser General Public License for more details. 26 * 27 * You should have received a copy of the GNU Lesser General Public 28 * License along with this library; if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 30 * USA 31 */ 32 33 package ch.elca.dependency.core; 34 35 import java.io.File; 36 import java.io.IOException; 37 import java.util.Hashtable; 38 import java.util.HashMap; 39 import java.util.HashSet; 40 import java.util.Enumeration; 41 import java.util.ListIterator; 42 import java.util.ArrayList; 43 44 import att.grappa.Edge; 45 import att.grappa.Graph; 46 import att.grappa.Node; 47 48 import ch.elca.dependency.exception.AnalyseException; 49 import ch.elca.dependency.graph.Perspective; 50 import ch.elca.dependency.graph.PerspectiveManager; 51 52 /*** 53 * It's the model in the MVC Design Pattern. 54 * 55 * This class contains the filtered graph model as well as the statistic data 56 * and the lists for generating the corresponding views. For every kind of data 57 * there are methods for getting this data to the view.<br> 58 * 59 * A set of observers are there for updating all the views attached to this 60 * model. Every time the model is changed by the controller, automatically all 61 * the views registred as an <code>Observer</code> are updated with the changed 62 * data.<br> 63 * If there are very serious changes performed on the model there is the 64 * possibility for disable the automated update mechanismus. This makes sense 65 * for example at startup when the whole model must be created or when a new 66 * filter is applicated which causes the model to change a lot. 67 * 68 * @see ch.elca.dependency.view.View 69 * @see ch.elca.dependency.rawmodel.RawModel 70 * 71 * @author Christoph Trutmann 72 * @author Pawel Kowalski 73 * @version 1.0-beta 74 */ 75 public class DependencyModel extends Hashtable implements Selection { 76 77 //****************************************************************************************/ 78 // static part of the model 79 //****************************************************************************************/ 80 81 private static DependencyModel s_dependencyModel = null; 82 83 /*** 84 * Get an instance of the <code>DependencyModel</code>, which is 85 * an singletong and must be creaated by the means of this method 86 * only. 87 * 88 * @return a <code>DependencyModel</code> value 89 */ 90 public static DependencyModel getDependencyModel() { 91 return s_dependencyModel; 92 } 93 94 //****************************************************************************************/ 95 // dynamic part of the model 96 //****************************************************************************************/ 97 98 /*** 99 * A key used to store and retrieve the MainFrame. 100 */ 101 public static final String MAIN_FRAME_KEY = "main-frame-key"; 102 103 /*** 104 * The list with all the Classinfo objects 105 */ 106 private HashMap m_filteredClassInfos; 107 108 /*** 109 * The graph component of the <code>DependencyModel</code>. 110 */ 111 private Graph m_filteredGraph; 112 113 /*** 114 * The Statistic component of the <code>DependencyModel</code>. 115 */ 116 private Statistic m_filteredStatistic; 117 118 /*** 119 * All the registred observer implementations are within this list.<br> 120 * I.e. all the existing views of this project. 121 */ 122 private ArrayList m_setOfObservers = new ArrayList(); 123 124 /*** 125 * This flag can be set false if the model should not notify the observer 126 * after each change in the model. This is useful in the case of an 127 * application of a new filter. Then a lot changes in the model and an 128 * actualisation after each of these changes would be not very good for the 129 * performance. 130 */ 131 private boolean m_notifyEnabled = true; 132 133 /*** 134 * Set containing all the <code>Edges</code> which are removed from the 135 * <code>Graph</code>. 136 */ 137 private HashSet m_removedEdges = new HashSet(); 138 139 /*** 140 * HashTable containing all the <code>Node</code> which are 141 * removed from the <code>Graph<code>. The name of the node 142 * element is the key for the hash map. Like this each node can 143 * be retrieved by using its name. 144 */ 145 private HashMap m_removedNodes = new HashMap(); 146 147 /*** 148 * Set containing all the packages of the last selection. 149 */ 150 private HashSet m_lastSelection = new HashSet(); 151 152 /*** 153 * A <code>DependencyContext</code> used to create this <code>DependencyModel</code>. 154 */ 155 private DependencyContext m_dependencyCtx = null; 156 157 /*** 158 * Support for StatusListeners. 159 */ 160 protected StatusListenerSupport m_statusListenerSupport = new StatusListenerSupport(); 161 162 /*** 163 * Available Perspectives. 164 */ 165 protected Perspective[] m_perspectives = null; 166 167 /*** 168 * A boolean indicating whether this model has been created already. 169 */ 170 private boolean m_created = false; 171 172 /*** 173 * The RawModel associated with this DependencyModel. 174 */ 175 private RawModel m_rawModel = null; 176 177 /*** 178 * Creates a new <code>DependencyModel</code> instance. Notice 179 * that altough an DependencyModel instance is created here, the 180 * DependencyModel is not created. Use isCreated() to check, 181 * whether this DependencyModel has really been created. 182 */ 183 public DependencyModel() { 184 } 185 186 /*** 187 * Creates a new <code>DependencyModel</code> instance. The 188 * specified DependencyContext will be used to create this 189 * DependencyModel. 190 * 191 * @param dependencyContext a <code>DependencyContext</code> value 192 * @exception AnalyseException if an error occurs 193 * @exception CloneNotSupportedException if an error occurs 194 * @exception IOException if an error occurs 195 * @exception ClassNotFoundException if an error occurs 196 */ 197 public DependencyModel(DependencyContext dependencyContext) 198 throws AnalyseException, CloneNotSupportedException, IOException, ClassNotFoundException { 199 create(dependencyContext); 200 } 201 202 /*** 203 * Create this DependencyModel accordingly to the specified DependencyContext. 204 * 205 * @param dependencyContext a <code>DependencyContext</code> value 206 * @exception AnalyseException if an error occurs 207 * @exception CloneNotSupportedException if an error occurs 208 * @exception IOException if an error occurs 209 * @exception ClassNotFoundException if an error occurs 210 */ 211 public void create(DependencyContext dependencyContext) 212 throws AnalyseException, CloneNotSupportedException, IOException, ClassNotFoundException { 213 m_dependencyCtx = dependencyContext; 214 215 File rootFile = (File)dependencyContext.get(DependencyContext.ROOT_FILE_KEY); 216 Filter basicFilter = (Filter)dependencyContext.get(DependencyContext.BASIC_FILTER_KEY); 217 218 m_statusListenerSupport.postMessage("analysing..."); 219 220 Analyzer analyzer = new Analyzer(rootFile, basicFilter); 221 222 m_statusListenerSupport.postMessage("creating model..."); 223 m_rawModel = new RawModel(analyzer); 224 225 // initialize the ClassInfo list 226 // 227 m_filteredClassInfos = (HashMap)m_rawModel.getRawClassInfos().clone(); 228 229 // initialize the statistic from the RawModel 230 // 231 m_filteredStatistic = (Statistic)m_rawModel.getRawStatistic().clone(); 232 233 // take the same graph object as initialized in the raw model 234 // the removed nodes are put in a separate list. 235 // 236 m_filteredGraph = m_rawModel.getRawGraph(); 237 238 m_created = true; 239 s_dependencyModel = this; 240 m_statusListenerSupport.postMessage(""); 241 } 242 243 /*** 244 * Is this DependencyModel created already? It might be possible 245 * that this DependencyModel is created as an Object, but is not 246 * really created. Such a DependencyModel cann't be used to 247 * retrieve information about the analyzed project. If a 248 * DependencyModel has been created successfully, this method will 249 * return <code>true</code>. 250 * 251 * @return a <code>boolean</code> value 252 */ 253 public boolean isCreated() { 254 return m_created; 255 } 256 257 /*** 258 * Get the DependencyContext which was used to create this DependencyModel. 259 * 260 * @return a <code>DependencyContext</code> value 261 */ 262 public DependencyContext getDependencyContext() { 263 return m_dependencyCtx; 264 } 265 266 /*** 267 * Get all Perspectives specified in a perspectives config file. 268 * 269 * @return a <code>Perspective[]</code> value 270 */ 271 public Perspective[] getPerspectives() { 272 273 // perspectives not yet loaded 274 // 275 if (m_perspectives == null) { 276 File perspectiveConfig = (File)m_dependencyCtx.get(DependencyContext.PERSPECTIVES_KEY); 277 if (perspectiveConfig != null) { 278 m_perspectives = PerspectiveManager.loadPerspectives(perspectiveConfig); 279 } else { 280 m_perspectives = new Perspective[] { Perspective.DEFAULT_PERSPECTIVE }; 281 } 282 } 283 284 return m_perspectives; 285 } 286 287 /*** 288 * Attaches the observers to the model. 289 * 290 * @param observer <code>Observer</code> Interface which is implemented by 291 * all the views ofthe DependencyTool. 292 */ 293 public void attach(Observer observer) { 294 m_setOfObservers.add(observer); 295 } 296 297 /*** 298 * Detaches the observers from the model. 299 * 300 * @param observer <code>Observer</code> Interface which is implemented by 301 * all the views ofthe DependencyTool. 302 */ 303 public void detach(Observer observer) { 304 m_setOfObservers.remove(observer); 305 } 306 307 /*** 308 * Gets the filtered <code>ClassInfo</code> objects. 309 * 310 * @return Filtered <code>ClassInfo</code> objects. 311 */ 312 public HashMap getFilteredClassInfos(){ 313 return m_filteredClassInfos; 314 } 315 316 /*** 317 * Gets the filtered <code>Graph</code> object. 318 * 319 * @return Filtered <code>Graph</code> object. 320 */ 321 public Graph getFilteredGraph() { 322 return m_filteredGraph; 323 } 324 325 /*** 326 * Gets the filtered <code>Statistic</code> object. 327 * 328 * @return Filtered <code>Statistic</code> object. 329 */ 330 public Statistic getFilteredStatistic(){ 331 return m_filteredStatistic; 332 } 333 334 /*** 335 * Select the same packages in each view. 336 * 337 * @param selectList List containing all the selected packages. 338 */ 339 public void selectPackages(ArrayList selectList){ 340 341 // the same is selected twice 342 // 343 if ( m_lastSelection.containsAll(selectList) ) { 344 return; 345 } 346 347 // select the apckages in all the views 348 // 349 ListIterator iter = m_setOfObservers.listIterator(); 350 while ( iter.hasNext() ) { 351 ((Observer)iter.next()).select(selectList); 352 } 353 354 // clear the list with the last packages 355 // 356 m_lastSelection.clear(); 357 358 // add the current selected packages 359 // 360 m_lastSelection.addAll(selectList); 361 } 362 363 /*** 364 * Clears all the selections in all the views. 365 */ 366 public void clearSelection(){ 367 // clear the selection in all the views 368 ListIterator iter = m_setOfObservers.listIterator(); 369 while ( iter.hasNext() ) { 370 ((Observer)iter.next()).clearSelection(); 371 } 372 // clear the list with the last packages 373 m_lastSelection.clear(); 374 } 375 376 /*** 377 * Gets the list with the last selected packages. 378 * 379 * @return a <code>HashSet</code> value 380 */ 381 public HashSet getLastSelection() { 382 return m_lastSelection; 383 } 384 385 /*** 386 * Iterates over all the observer objects and calls the update method. 387 */ 388 public void notifyObserver() { 389 if( ! m_notifyEnabled ) { 390 return; 391 } 392 393 ListIterator iter = m_setOfObservers.listIterator(); 394 while( iter.hasNext() ) { 395 ((Observer)iter.next()).update(this); 396 } 397 } 398 399 /*** 400 * Sets the notification flag false. I.e. the model is not updated until 401 * this flag is not set true. 402 */ 403 public void disableNotification() { 404 m_notifyEnabled = false; 405 } 406 407 /*** 408 * Sets the notification flag true and notifies the observer. 409 */ 410 public void enableNotification() { 411 m_notifyEnabled = true; 412 notifyObserver(); 413 } 414 415 /*** 416 * Clears all the <code>ClassInfo</code> objects in the list of the 417 * <code>DependencyModel</code>. 418 */ 419 public void clearClassInfos(){ 420 m_filteredClassInfos.clear(); 421 notifyObserver(); 422 } 423 424 /*** 425 * Clears all the <code>Vertices</code> and <code>Edges</code> from the 426 * current <code>DependencyModel</code>. 427 */ 428 public void clearGraph() { 429 430 // remove all the nodes in the graph and add them to the HashMap. 431 // 432 Enumeration nodeEnum = m_filteredGraph.nodeElements(); 433 while ( nodeEnum.hasMoreElements() ) { 434 String nodeName = ((Node)nodeEnum.nextElement()).getName(); 435 Node nodeTmp = m_filteredGraph.removeNode(nodeName); 436 437 m_removedNodes.put(nodeName, nodeTmp); 438 } 439 440 // remove all the edges in the graph and add them to the HashMap. 441 // 442 Enumeration edgeEnum = m_filteredGraph.edgeElements(); 443 while ( edgeEnum.hasMoreElements() ) { 444 String edgeName = ((Edge)edgeEnum.nextElement()).getName(); 445 Edge edgeTmp = m_filteredGraph.removeEdge(edgeName); 446 if ( edgeTmp == null ) { 447 System.out.println("Edge '" + edgeName + "' is not removed!!"); 448 } 449 m_removedEdges.add(edgeTmp); 450 } 451 notifyObserver(); 452 } 453 454 /*** 455 * Adds the specified <code>Classinfo</code> to the model. 456 * 457 * @param classInfoList Information object of one class of the project. 458 * @param pack a <code>String</code> value 459 */ 460 public void add(ArrayList classInfoList, String pack) { 461 m_filteredClassInfos.put(pack, classInfoList); 462 notifyObserver(); 463 } 464 465 /*** 466 * Adds the specified <code>Node</code> to the model. 467 * 468 * @param node Node to be added. 469 */ 470 public void add(Node node) { 471 472 // remove node in the removed hash map 473 // 474 String nodeName = node.getName(); 475 if ( m_removedNodes.containsKey(nodeName) ) { 476 m_removedNodes.remove(nodeName); 477 } 478 479 // add node to the graph 480 // 481 m_filteredGraph.addNode(node); 482 notifyObserver(); 483 } 484 485 /*** 486 * Adds the specified <code>Edge</code> to the model. 487 * 488 * @param edge Edge to add to the model. 489 */ 490 public void add(Edge edge) { 491 492 // remove edge in the removed hash set 493 // 494 if ( m_removedEdges.contains(edge) ) { 495 m_removedEdges.remove(edge); 496 } 497 498 // add edge to the graph 499 // 500 m_filteredGraph.addEdge(edge); 501 notifyObserver(); 502 } 503 504 /*** 505 * Get the Set with the removed <code>Edges</code>. 506 * 507 * @return HashSet with the removed <code>Edge</code> elements. 508 */ 509 public HashSet getRemovedEdges(){ 510 return m_removedEdges; 511 } 512 513 /*** 514 * Get the <code>HashTable</code> with the removed <code>Node</code>. 515 * 516 * @return HashSet with the removed <code>Node</code> elements. 517 */ 518 public HashMap getRemovedNodes(){ 519 return m_removedNodes; 520 } 521 522 /*** 523 * Append a StatusListeners to this DependencyModel. A 524 * StatusListener will be noticed in case a StatusEvent occurs. 525 * 526 * @param statusListener a <code>StatusListener</code> value 527 */ 528 public void setStatusListener(StatusListener statusListener) { 529 m_statusListenerSupport.setStatusListener(statusListener); 530 } 531 532 /*** 533 * Get RawClassInfos from this DependencyModel. 534 * 535 * @return a <code>HashMap</code> value 536 */ 537 public HashMap getRawClassInfos(){ 538 return m_rawModel.getRawClassInfos(); 539 } 540 541 /*** 542 * Get the RawGraph from this DependencyModel. 543 * 544 * @return a <code>Graph</code> value 545 */ 546 public Graph getRawGraph() { 547 return m_rawModel.getRawGraph(); 548 } 549 550 /*** 551 * Get all Package dependencies from this DependencyModel. 552 * 553 * @return a <code>HashMap</code> value 554 */ 555 public HashMap getPackDepend() { 556 return m_rawModel.getPackDepend(); 557 } 558 559 /*** 560 * Get the Project Root. 561 * 562 * @return a <code>File</code> value 563 */ 564 public File getProjectRoot() { 565 return m_rawModel.getProjectRoot(); 566 } 567 568 /*** 569 * Get the list of all nodes representing packages in the analyzed project. 570 * 571 * @return an <code>ArrayList</code> value 572 */ 573 public ArrayList getNodeList() { 574 return m_rawModel.getNodeList(); 575 } 576 577 /*** 578 * Get the RawModel from this DependencyModel. 579 * 580 * @return a <code>RawModel</code> value 581 */ 582 public RawModel getRawModel() { 583 return m_rawModel; 584 } 585 }

This page was automatically generated by Maven