1 19 20 28 29 package org.netbeans.modules.xml.schema.refactoring.query.readers; 30 31 import java.awt.Color ; 32 import java.awt.Image ; 33 import java.beans.BeanInfo ; 34 import java.text.MessageFormat ; 35 import java.util.ArrayList ; 36 import java.util.Collection ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.Map ; 40 import java.util.Map.Entry; 41 import java.util.MissingResourceException ; 42 import java.util.Set ; 43 import java.util.concurrent.ExecutionException ; 44 import org.netbeans.api.project.SourceGroup; 45 import org.netbeans.modules.xml.nbprefuse.AnalysisConstants; 46 import org.netbeans.modules.xml.refactoring.FindUsageResult; 47 import org.netbeans.modules.xml.refactoring.RefactoringManager; 48 import org.netbeans.modules.xml.refactoring.Usage; 49 import org.netbeans.modules.xml.refactoring.UsageGroup; 50 import org.netbeans.modules.xml.refactoring.UsageSet; 51 import org.netbeans.modules.xml.refactoring.spi.UIHelper; 52 import org.netbeans.modules.xml.refactoring.ui.util.AnalysisUtilities; 53 import org.netbeans.modules.xml.schema.model.ComplexContentRestriction; 54 import org.netbeans.modules.xml.schema.model.ComplexExtension; 55 import org.netbeans.modules.xml.schema.model.GlobalComplexType; 56 import org.netbeans.modules.xml.schema.refactoring.ui.DisplayInfoVisitor; 57 import org.netbeans.modules.xml.xam.Component; 58 import org.netbeans.modules.xml.xam.Model; 59 import org.netbeans.modules.xml.xam.Named; 60 import org.netbeans.modules.xml.xam.Referenceable; 61 import org.openide.ErrorManager; 62 import org.openide.awt.StatusDisplayer; 63 import org.openide.filesystems.FileObject; 64 import org.openide.filesystems.FileUtil; 65 import org.openide.util.NbBundle; 66 import prefuse.data.Edge; 67 import prefuse.data.Graph; 68 import prefuse.data.Node; 69 70 71 77 public class ComplexTypeDerivationsReader { 78 79 80 private static final DisplayInfoVisitor div = new DisplayInfoVisitor(); 82 83 84 public static final prefuse.data.Schema FIND_USAGES_NODES_SCHEMA = 85 new prefuse.data.Schema(); static { 87 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.LABEL, 88 String .class, AnalysisConstants.EMPTY_STRING); 89 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.ID, 90 String .class, AnalysisConstants.EMPTY_STRING); 91 FIND_USAGES_NODES_SCHEMA.addColumn( 92 AnalysisConstants.COMPONENT_TYPE_NAME, 93 String .class, AnalysisConstants.EMPTY_STRING); 94 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.ELEMENT_TYPE, 95 String .class, AnalysisConstants.EMPTY_STRING); 96 98 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.XML_FILENAME, 99 String .class, AnalysisConstants.EMPTY_STRING); 100 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.FILE_OBJECT, 101 FileObject.class); 102 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.FILE_TYPE, 103 String .class, AnalysisConstants.EMPTY_STRING); 104 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.TOOLTIP, 105 String .class, AnalysisConstants.EMPTY_STRING); FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.XAM_COMPONENT, 107 Component.class); 108 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.OPENIDE_NODE, 109 org.openide.nodes.Node.class); 110 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.JAVA_AWT_IMAGE, 111 Image .class); 112 113 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.FILE_GROUP, 120 int.class, -1); 121 FIND_USAGES_NODES_SCHEMA.addColumn( 124 AnalysisConstants.FILE_NODE_FILE_GROUP, int.class, -1); 125 127 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.IS_PRIMITIVE, 128 boolean.class, false); FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.IS_QUERY_NODE, 130 boolean.class, false); 131 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.IS_USAGE_NODE, 132 boolean.class, false); 133 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.IS_FILE_NODE, 134 boolean.class, false); 135 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.IS_EXPANDED, 136 boolean.class, false); 137 FIND_USAGES_NODES_SCHEMA.addColumn(AnalysisConstants.MOUSEOVER, 138 boolean.class, false); 139 } 140 141 142 143 public static final prefuse.data.Schema FIND_USAGES_EDGES_SCHEMA = 144 new prefuse.data.Schema(); static { 146 FIND_USAGES_EDGES_SCHEMA.addColumn(AnalysisConstants.LABEL, 147 String .class, AnalysisConstants.EMPTY_STRING); 148 FIND_USAGES_EDGES_SCHEMA.addColumn(AnalysisConstants.EDGE_TYPE, 149 String .class, AnalysisConstants.EMPTY_STRING); 150 152 FIND_USAGES_EDGES_SCHEMA.addColumn(AnalysisConstants.TOOLTIP, 153 String .class, AnalysisConstants.EMPTY_STRING); 154 FIND_USAGES_EDGES_SCHEMA.addColumn(AnalysisConstants.FILE_GROUP, 161 int.class, -1); 162 } 163 164 167 public ComplexTypeDerivationsReader() { 168 169 } 170 171 172 176 177 @SuppressWarnings ("unchecked") 178 public Graph loadComplexTypeDerivationsGraph( 179 GlobalComplexType baseCT) { 180 if (baseCT == null){ 182 StatusDisplayer.getDefault().setStatusText(""); ErrorManager.getDefault().log( 184 "WhereUsedReader.loadComplexTypeDerivationsGraph()" + 185 " found null query base CT"); return null; 187 } 188 int fileGroupNumber = 0; 190 List <Integer > derivationsCount = new ArrayList <Integer >(); 192 derivationsCount.add(Integer.valueOf(0)); derivationsCount.add(Integer.valueOf(0)); Graph graph = new Graph(true); graph.getNodeTable().addColumns(FIND_USAGES_NODES_SCHEMA); 196 graph.getEdgeTable().addColumns(FIND_USAGES_EDGES_SCHEMA); 197 198 List <Component> componentsInGraph = new ArrayList <Component>(); 199 200 org.openide.nodes.Node displayNode = null; 201 202 Named ref = baseCT; 203 FindUsageResult result = RefactoringManager.getInstance().findUsages(baseCT, 204 baseCT.getModel().getSchema()); 205 UsageSet usageSet = null; 206 try { 207 usageSet = result.get(); 208 } catch (InterruptedException ex) { 209 ErrorManager.getDefault().notify(ex); 210 } catch (ExecutionException ex) { 211 ErrorManager.getDefault().notify(ex); 212 } 213 214 UIHelper queryUIHelper = getUIHelper(baseCT); 215 Node queryNode = createQueryNode(graph, 216 baseCT, 217 queryUIHelper, 218 false, 219 componentsInGraph, 220 false, 221 fileGroupNumber); 222 if (queryUIHelper != null){ 223 displayNode = queryUIHelper.getDisplayNode(baseCT); 224 } 225 queryNode.set(AnalysisConstants.COMPONENT_TYPE_NAME, 226 displayNode.getShortDescription()); queryNode.set(AnalysisConstants.XAM_COMPONENT, 228 baseCT); 229 queryNode.setString(AnalysisConstants.LABEL, displayNode.getName()); 230 queryNode.setString(AnalysisConstants.ELEMENT_TYPE, 231 displayNode.getDisplayName()); 233 Map <SourceGroup, Map <FileObject,Set <UsageGroup>>> sortedUses = 235 usageSet.getSortedUsages(); 236 Set <Entry<SourceGroup,Map <FileObject,Set <UsageGroup>>>> sgUses = 237 sortedUses.entrySet(); 238 int usagesCount = 0; 239 for (Entry<SourceGroup, Map <FileObject, Set <UsageGroup>>> sgUse:sgUses){ 240 Set <Entry<FileObject,Set <UsageGroup>>> pkgUses = sgUse.getValue().entrySet(); 241 for (Entry<FileObject, Set <UsageGroup>> pkgUse:pkgUses){ 242 Set <UsageGroup> usages = pkgUse.getValue(); 243 for (UsageGroup usage:usages){ 244 int count = usage.getItems().size(); 245 if (count < 1){ 246 continue; 247 } 248 usagesCount += count; 249 fileGroupNumber++; 250 addUsagesToGraph(true, usage, 252 graph, 253 false, componentsInGraph, 255 baseCT.getModel(), 256 baseCT, 257 queryNode, 258 fileGroupNumber, 259 derivationsCount); 260 261 } 262 } 263 } 264 265 266 writeDerivationsFoundStatusMessage(derivationsCount.get(0).intValue(), 267 derivationsCount.get(1).intValue(), baseCT); 268 return graph; 269 } 270 271 private void writeDerivationsFoundStatusMessage(final int extensionCount, 272 final int restrictionCount, GlobalComplexType baseCT) 273 throws MissingResourceException { 274 if (baseCT == null){ 275 ErrorManager.getDefault().log( 276 "WhereUsedReader.loadComplexTypeDerivationsGraph()" + 277 " found null query base CT"); } 279 280 String extensionMsg = null; 281 if (extensionCount == 1){ 282 extensionMsg = NbBundle.getMessage(ComplexTypeDerivationsReader.class, 283 "LBL_Found_1_Extension"); 284 } else { 285 extensionMsg = MessageFormat.format(NbBundle.getMessage( 286 ComplexTypeDerivationsReader.class, 287 "LBL_Found_Extensions"), 288 new Object [] { 289 extensionCount 290 } 291 ) ; 292 } 293 294 String restrictionMsg = null; 295 if (restrictionCount == 1){ 296 restrictionMsg = MessageFormat.format(NbBundle.getMessage( 297 ComplexTypeDerivationsReader.class, 298 "LBL_1_Restriction_On_Complex_Type"), 299 new Object [] { 300 baseCT.getName() 301 } 302 ) ; 303 } else { 304 restrictionMsg = MessageFormat.format(NbBundle.getMessage( 305 ComplexTypeDerivationsReader.class, 306 "LBL_Restrictions_On_Complex_Type"), 307 new Object [] { 308 restrictionCount, 309 baseCT.getName() 310 } 311 ) ; 312 } 313 if (!(extensionMsg == null || restrictionMsg == null)){ 314 StatusDisplayer.getDefault().setStatusText( 315 extensionMsg + restrictionMsg); 316 317 } 318 } 319 320 321 322 323 private UIHelper getUIHelper(Referenceable ref) { 324 return RefactoringManager.getInstance().getTargetComponentUIHelper(ref); 325 } 326 327 340 private void addUsagesToGraph(boolean ctDerivationsOnly, 341 UsageGroup usage, 342 Graph graph, 343 boolean isPrimitive, 344 List <Component> componentsInGraph, 345 Model model, 346 Component queryComponent, 347 Node queryNode, 348 int fileGroupNumber, 349 List <Integer > derivationsCount) { 350 351 Collection <Usage> items = usage.getItems(); 353 UIHelper uiHelper = usage.getEngine().getUIHelper(); 354 355 359 Node fileNode = null; 371 for (Usage item:items){ 372 if (ctDerivationsOnly){ 373 Component usageComponent = item.getComponent(); 374 if (usageComponent instanceof ComplexContentRestriction){ 375 derivationsCount.set(1,derivationsCount.get(1)+1); 376 } else if (usageComponent instanceof ComplexExtension){ 377 derivationsCount.set(0,derivationsCount.get(0)+1); 378 } else{ 379 continue; } 381 } 382 if (fileNode == null){ 384 fileNode = createFileNode(graph, 385 queryComponent, 386 (FileObject)usage.getModel().getModelSource().getLookup().lookup(FileObject.class), 387 queryNode, 388 fileGroupNumber); 389 } 390 List <Component> aPath = uiHelper.getRelevantPathFromRoot(item); 391 Node parent = null; 392 for (int i = 0; i < aPath.size();i++){ 393 Component sc = aPath.get(i); 394 Node pn = null; 395 AnalysisUtilities.ToolTipLine topLine = null; 396 397 if (componentsInGraph.contains(sc)){ 398 pn = findDup(graph, sc); 401 assert pn != null:"Cannot find Node for Component " 402 + 403 sc; } 405 406 if (pn == null){ 407 pn = createNode(graph, 408 sc, 409 uiHelper, 410 false, 411 componentsInGraph, 412 queryComponent, 413 fileGroupNumber); 414 } 415 416 if (i == 0){ 417 AnalysisUtilities.ToolTipLine typeLine = 419 new AnalysisUtilities.ToolTipLine(pn.getString(AnalysisConstants.COMPONENT_TYPE_NAME), 420 100, 421 Color.BLACK.getRGB(), 422 AnalysisUtilities.ToolTipLine. 423 HorizontalAlignment.CENTER); 424 String toolTip = AnalysisUtilities.createHTMLToolTip( 425 new AnalysisUtilities.ToolTipLine[] {topLine, typeLine}); 426 pn.setString(AnalysisConstants.TOOLTIP, toolTip); 427 428 Edge fileCompositionEdge = graph.addEdge(pn,fileNode); 430 fileCompositionEdge.setString(AnalysisConstants.EDGE_TYPE, 431 AnalysisConstants.COMPOSITION); 432 fileCompositionEdge.setInt(AnalysisConstants.FILE_GROUP, 436 fileGroupNumber); 437 438 parent = pn; 440 } else { 441 442 AnalysisUtilities.ToolTipLine typeLine = 443 new AnalysisUtilities.ToolTipLine(getCompTypeDisplayName(pn), 444 100, 445 Color.BLACK.getRGB(), 446 AnalysisUtilities.ToolTipLine. 447 HorizontalAlignment.CENTER); 448 String toolTip = AnalysisUtilities.createHTMLToolTip( 449 new AnalysisUtilities.ToolTipLine[] {topLine, typeLine}); 450 pn.setString(AnalysisConstants.TOOLTIP, toolTip); 451 452 453 if (parent != null){ 455 addCompositionEdge(graph, 456 pn, 457 parent, 458 fileGroupNumber); 459 } 460 parent = pn; 461 } 462 463 464 if (i == aPath.size()-1){ 466 pn.setBoolean( 468 AnalysisConstants.IS_USAGE_NODE, true); 469 470 topLine = new AnalysisUtilities.ToolTipLine(( 471 MessageFormat.format(NbBundle.getMessage( 472 ComplexTypeDerivationsReader.class, "LBL_Uses_Component"), 473 new Object [] {queryNode.getString( 474 AnalysisConstants.LABEL) })), 475 100, 476 Color.BLACK.getRGB(), 477 AnalysisUtilities.ToolTipLine. 478 HorizontalAlignment.CENTER); 479 addApppropriateEdge(graph, 482 pn, 483 queryNode, 484 fileGroupNumber, 485 item.getType()); 486 487 } 489 } 490 } 491 } 493 494 495 private static String getCompTypeDisplayName(final Node pn) throws MissingResourceException { 496 String compType = null; 497 if (pn.canGetBoolean(AnalysisConstants.IS_PRIMITIVE) && 498 pn.getBoolean(AnalysisConstants.IS_PRIMITIVE)){ 499 compType = NbBundle.getMessage(ComplexTypeDerivationsReader.class, 500 "LBL_Primitive_Type"); 501 } else { 502 compType = pn.getString(AnalysisConstants.COMPONENT_TYPE_NAME); 503 } 504 return compType; 505 } 506 507 private void addCompositionEdge(Graph graph, Node part, Node whole, 508 int fileGroupNumber){ 509 Edge edge = graph.addEdge(part, whole); 510 edge.setString(AnalysisConstants.EDGE_TYPE, 512 AnalysisConstants.COMPOSITION); 513 edge.setInt(AnalysisConstants.FILE_GROUP, Integer.valueOf(fileGroupNumber)); 514 515 } 516 517 523 private void addApppropriateEdge(Graph graph, Node from, Node queryNode, 524 int fileGroupNumber, Usage.Type edgeType){ 525 Edge edge = graph.addEdge(from, queryNode); 526 528 edge.setInt(AnalysisConstants.FILE_GROUP, Integer.valueOf(fileGroupNumber)); 529 if ( edgeType == Usage.Type.GENERALIZATION){ 530 edge.setString(AnalysisConstants.EDGE_TYPE, 531 AnalysisConstants.GENERALIZATION); 532 } else if ( edgeType == Usage.Type.REFERENCE){ 533 edge.setString(AnalysisConstants.EDGE_TYPE, 534 AnalysisConstants.REFERENCE); 535 from.setString(AnalysisConstants.LABEL, 536 MessageFormat.format(NbBundle.getMessage( 537 ComplexTypeDerivationsReader.class, 538 "LBL_References_Ref"), 539 new Object [] 540 {queryNode.getString(AnalysisConstants.LABEL)})); 541 } 542 } 543 544 private Node findDup(Graph graph, Component sc){ 545 Iterator it = graph.nodes(); 546 while (it.hasNext()){ 547 Node n= Node.class.cast(it.next()); 548 Object nodeSC = n.get(AnalysisConstants.XAM_COMPONENT); 549 if ((n.canGetBoolean(AnalysisConstants.IS_FILE_NODE) && 550 n.getBoolean(AnalysisConstants.IS_FILE_NODE) == false) 551 && nodeSC != null){ 552 if (nodeSC == sc){ 553 return n; 554 } 555 } 556 } 557 return null; 558 } 559 560 public static Node createQueryNode(Graph graph, 561 Component query, 562 UIHelper uiHelper, 563 boolean isPrimitive, 564 List <Component> componentsInGraph, 565 boolean showOnlyDerivations, 566 int fileGroupNumber 567 ) { 568 Node queryNode = null; 570 if (uiHelper == null){ 571 String name = ""; if (query instanceof Named){ 573 name = ((Named)Named.class.cast(query)).getName(); 574 } 575 queryNode = graph.addNode(); 576 componentsInGraph.add(query); 577 queryNode.setBoolean(AnalysisConstants.IS_PRIMITIVE, isPrimitive); 578 queryNode.setString(AnalysisConstants.LABEL, name); 579 queryNode.setString(AnalysisConstants.COMPONENT_TYPE_NAME, "" ); queryNode.set(AnalysisConstants.XAM_COMPONENT, query ); 581 queryNode.setInt(AnalysisConstants.FILE_GROUP, fileGroupNumber); 582 583 } else { 584 queryNode = createNode(graph, query, uiHelper, isPrimitive, componentsInGraph, query, fileGroupNumber); 585 } 586 587 queryNode.setBoolean(AnalysisConstants.IS_QUERY_NODE, true); 588 queryNode.setInt(AnalysisConstants.FILE_GROUP,-1); 590 queryNode.setBoolean(AnalysisConstants.IS_PRIMITIVE, isPrimitive); 592 593 AnalysisUtilities.ToolTipLine topLine = new AnalysisUtilities.ToolTipLine(( 594 showOnlyDerivations? 595 NbBundle.getMessage(ComplexTypeDerivationsReader.class, 596 "LBL_Base_Complex_Type"): 597 NbBundle.getMessage(ComplexTypeDerivationsReader.class, 598 "LBL_Query_Component")), 599 100, 600 Color.BLACK.getRGB(), 601 AnalysisUtilities.ToolTipLine.HorizontalAlignment.CENTER); 602 String compType = getCompTypeDisplayName(queryNode); 603 AnalysisUtilities.ToolTipLine typeLine = new AnalysisUtilities.ToolTipLine( 604 compType, 605 100, 606 Color.BLACK.getRGB(), 607 AnalysisUtilities.ToolTipLine.HorizontalAlignment.CENTER); 608 String toolTip = AnalysisUtilities.createHTMLToolTip(new AnalysisUtilities.ToolTipLine[] { 609 topLine, typeLine}); 610 611 queryNode.setString(AnalysisConstants.TOOLTIP, toolTip); 612 return queryNode; 613 } 614 615 616 private Node createFileNode(Graph graph, Component queryComp, 617 FileObject fobj, Node queryNode, int fileGroupNumber){ 618 if (queryComp == null || fobj == null){ 619 return null; 620 } 621 String fileType = AnalysisUtilities.getXmlFileType(fobj); 622 Node n = graph.addNode(); 623 n.setString(AnalysisConstants.FILE_TYPE,fileType); 624 n.setInt(AnalysisConstants.FILE_NODE_FILE_GROUP, fileGroupNumber); 625 n.setBoolean(AnalysisConstants.IS_EXPANDED, false); 626 n.setBoolean(AnalysisConstants.IS_FILE_NODE, true); 627 n.set(AnalysisConstants.JAVA_AWT_IMAGE, AnalysisUtilities.getImage(fobj)); 628 n.setString(AnalysisConstants.LABEL, fobj.getNameExt()); 629 n.setString(AnalysisConstants.XML_FILENAME, fobj.getNameExt()); 630 n.set(AnalysisConstants.FILE_OBJECT, fobj); 631 632 AnalysisUtilities.ToolTipLine topLine = new AnalysisUtilities.ToolTipLine( 634 MessageFormat.format( 635 NbBundle.getMessage(ComplexTypeDerivationsReader.class, 636 "LBL_Xml_File_With_Usages"),new Object []{ 637 AnalysisUtilities.getXmlFileTypeDisplayName(fileType), 638 queryNode.getString(AnalysisConstants.LABEL)}), 639 100, 640 Color.BLACK.getRGB(), 641 AnalysisUtilities.ToolTipLine.HorizontalAlignment.CENTER); 642 AnalysisUtilities.ToolTipLine typeLine = 643 new AnalysisUtilities.ToolTipLine( 644 FileUtil.getFileDisplayName(fobj), 645 100, 646 Color.BLACK.getRGB(), 647 AnalysisUtilities.ToolTipLine.HorizontalAlignment.CENTER); 648 String toolTip = AnalysisUtilities.createHTMLToolTip( 649 new AnalysisUtilities.ToolTipLine[] {topLine, typeLine}); 650 651 n.setString(AnalysisConstants.TOOLTIP, 652 toolTip); 653 return n; 654 } 655 659 public static Node createNode(Graph graph, 660 Component comp, 661 UIHelper uiHelper, 662 boolean isPrimitive, 663 List <Component> componentsInGraph, 664 Component queryComponent, 665 int fileGroupNumber 666 ){ 667 Node n = graph.addNode(); 668 if (componentsInGraph != null){ 669 componentsInGraph.add(comp); 670 } 671 org.openide.nodes.Node displayNode = uiHelper.getDisplayNode(comp); 673 674 if (isPrimitive){ 678 if (comp.getModel() == 679 queryComponent.getModel()) { 680 n.setBoolean(AnalysisConstants.IS_PRIMITIVE, true); 681 } 682 } 683 n.setBoolean(AnalysisConstants.IS_PRIMITIVE, false); 684 n.setString(AnalysisConstants.LABEL, displayNode.getName()); 685 n.setString(AnalysisConstants.COMPONENT_TYPE_NAME, displayNode.getShortDescription() ); 686 n.set(AnalysisConstants.XAM_COMPONENT, comp ); 687 n.set(AnalysisConstants.OPENIDE_NODE, displayNode ); 688 n.setInt(AnalysisConstants.FILE_GROUP, fileGroupNumber); 689 n.set(AnalysisConstants.JAVA_AWT_IMAGE, displayNode.getIcon(BeanInfo.ICON_COLOR_16x16)); 690 691 return n; 692 } 693 694 695 } 696 | Popular Tags |