001 package nl.cwi.sen1.visbase.factbrowser; 002 003 import java.awt.event.MouseEvent; 004 import java.util.Iterator; 005 006 import javax.swing.tree.DefaultMutableTreeNode; 007 008 import nl.cwi.sen1.configapi.Factory; 009 import nl.cwi.sen1.configapi.types.ActionDescriptionList; 010 import nl.cwi.sen1.configapi.types.Event; 011 import nl.cwi.sen1.gui.CloseAbortedException; 012 import nl.cwi.sen1.gui.Studio; 013 import nl.cwi.sen1.gui.StudioImplWithPredefinedLayout; 014 import nl.cwi.sen1.gui.StudioWithPredefinedLayout; 015 import nl.cwi.sen1.gui.component.StudioComponent; 016 import nl.cwi.sen1.gui.component.StudioComponentImpl; 017 import nl.cwi.sen1.gui.plugin.DefaultStudioPlugin; 018 import nl.cwi.sen1.relationstores.types.RType; 019 import nl.cwi.sen1.util.DefaultPopupImpl; 020 import nl.cwi.sen1.util.MouseAdapter; 021 import nl.cwi.sen1.visbase.factbrowser.data.FactBrowserDataManager; 022 import nl.cwi.sen1.visbase.factbrowser.data.RStore; 023 import nl.cwi.sen1.visbase.factbrowser.data.RStoreFact; 024 import nl.cwi.sen1.visbase.factbrowser.data.VisualisationPlugin; 025 import nl.cwi.sen1.visbase.rstorecontainer.datatypes.ATermParseException; 026 import nl.cwi.sen1.visbase.rstorecontainer.datatypes.FactInfo; 027 import nl.cwi.sen1.visbase.rstorecontainer.datatypes.FactInfoList; 028 029 import org.apache.commons.logging.Log; 030 import org.apache.commons.logging.LogFactory; 031 032 import aterm.ATerm; 033 import aterm.ATermList; 034 import aterm.pure.PureFactory; 035 036 /** 037 * This class is the main entry point for the toolbus FactBrowserInterface 038 * script. It also listens to event from the FactBrowserWindow with the visual 039 * tree containing the RStores 040 * 041 * <b>DataManager</b> This method has a dataManager which takes care of the 042 * registration of new Rstores/Facts/FactTypes and VisualisationPlugins. 043 * 044 * <b>RTypes decoding</b> For the decoding of the given Facts with Rtypes, the 045 * rstore-container FactInfoList()is used. This will get a container class with 046 * all the nessecary information about the Facts. 047 * 048 * @extends DefaultStudioPlungin This class makes it possible to add this class 049 * as a plugin in the Meta-Environment. 050 * 051 * @implemented FactBrowserTif This is the interface containing the methods 052 * responsible for the communication with the toolbus 053 * 054 * @author Renze de Vries 055 * @Date 12-02-2007 056 */ 057 public class FactBrowser extends DefaultStudioPlugin implements FactbrowserTif { 058 private static final int DOUBLE_CLICK = 2; 059 060 private FactBrowserDataManager dataManager; 061 062 private static final String TOOL_NAME = "factbrowser"; 063 064 private static final Log log = LogFactory.getLog(FactBrowser.class); 065 066 private Factory configFactory; 067 068 private Studio studio; 069 070 private StudioComponent component; 071 072 private FactbrowserBridge bridge; 073 074 private FactBrowserWindow factBrowserWindow; 075 076 private DefaultPopupImpl popup; 077 078 /** 079 * This is the default constructor it creates the dataManager and the 080 * visualisationClass 081 * 082 * @author Renze de Vries 083 * @date 22-02-2007 084 */ 085 public FactBrowser() { 086 dataManager = FactBrowserDataManager.getInstance(); 087 factBrowserWindow = new FactBrowserWindow(); 088 } 089 090 /** 091 * <b>ToolbusInterface</b> This method is a toolBus interface required 092 * implementation. It gets as parameters the type of the visualisation, name 093 * and the identifier for the plugin. It passes the visualisation to the 094 * dataManager and signals the visualisationWindow to redraw. 095 * 096 * 097 * @param pluginType 098 * @param pluginIdentifier 099 * @param pluginName1 100 * 101 * @author Renze de Vries 102 * @date 20-02-2007 103 */ 104 public void fbAddVisualizationPlugin(ATerm pluginType, 105 int pluginIdentifier, String pluginName) { 106 log.debug("Incoming Visualisation plugin with name: " + pluginName 107 + " and identifier: " + pluginIdentifier); 108 log.debug("Incoming Visualisation plugin with type: " 109 + pluginType.toString()); 110 111 VisualisationPlugin visPlugin = new VisualisationPlugin(pluginName, 112 pluginIdentifier); 113 dataManager.createVisualisation(visPlugin, dataManager 114 .addFactType(pluginType.toString())); 115 116 factBrowserWindow.redrawTree(); 117 } 118 119 /** 120 * <b>ToolbusInterface</b> This method is an interface for the toolbus 121 * communications. It's task is to add a passed Rstore with all it's 122 * children facts to the dataStore which is managed by the (caching) 123 * dataManager. 124 * 125 * @param rstoreName 126 * @param rstoreIdentifier 127 * @param rstoreFacts 128 * 129 * @author Renze de Vries 130 * @date 20-02-2007 131 */ 132 public void fbShowRstoreFacts(String rstoreName, int rstoreIdentifier, 133 ATerm rstoreFacts) { 134 135 // Create the RStoreNode and set the parameters Name and Identifier 136 RStore rstoreNode = new RStore(rstoreName, rstoreIdentifier); 137 138 // We want to create all children FactNodes so Create a FactInfoList 139 FactInfoList factInfoList = null; 140 try { 141 // Put the ATerm containing the RStore facts in the List 142 factInfoList = new FactInfoList((ATermList) rstoreFacts); 143 144 // Iterate through FactInfo list 145 for (FactInfo factInfo : factInfoList.getFactInfos()) { 146 // Create a new factNode so we can add them to the in memory 147 // tree 148 RStoreFact factNode = new RStoreFact(factInfo.getName(), 149 factInfo.getId(), dataManager.addFactType(factInfo 150 .getType())); 151 152 factNode.setRType(factInfo.getRType()); 153 154 // add them to the parent RStore 155 rstoreNode.addFactNode(factNode); 156 } 157 158 } catch (ATermParseException e) { 159 e.printStackTrace(); 160 } 161 162 // Finally add the Rstore to the visual tree 163 factBrowserWindow.addRStore(rstoreNode); 164 165 Iterator<RStoreFact> iterator = rstoreNode.getFactNodes().iterator(); 166 while (iterator.hasNext()) { 167 RType rtype = iterator.next().getRType(); 168 169 ATerm term = studio.getATermFactory().make( 170 "fb-type-selected(<term>)", rtype.toTerm()); 171 bridge.sendEvent(term); 172 } 173 174 studio.makeVisible(component); 175 } 176 177 /** 178 * Removes the rstore with the specified rstoreIdentifier from the tree. 179 * 180 * @author Bas Basten 181 * @author Anton Lycklama a Nijeholt 182 * @date 19-03-2007 183 * 184 * @param rstoreIdentifier 185 */ 186 public void fbRstoreUnloaded(int rstoreIdentifier) { 187 factBrowserWindow.removeRStoreTreeNode(rstoreIdentifier); 188 } 189 190 /** 191 * Method must be implemented as part of toolbus compliance 192 */ 193 public void recAckEvent(ATerm t0) { 194 } 195 196 /** 197 * Method will be called when the connection with the toolbus is terminated 198 */ 199 public void recTerminate(ATerm t0) { 200 fireStudioPluginClosed(); 201 } 202 203 /** 204 * This method returns the name of this Tool for the metaStudio. 205 */ 206 public String getName() { 207 return TOOL_NAME; 208 } 209 210 private ATerm createEventId(ATerm moduleId) { 211 return studio.getATermFactory().make(TOOL_NAME + "(<term>)", moduleId); 212 } 213 214 /** 215 * This is the entry method for the FactBrowser. When the meta-environment 216 * is started this will be called to add the factBrowser to the studio. It 217 * calls a method which will load the layout with the menu's. 218 * 219 * @param metaStudio 220 * This is the instance of the metaStudio 221 * 222 * @author Renze de Vries 223 * @date 20-02-2007 224 */ 225 public void initStudioPlugin(Studio metaStudio) { 226 this.studio = metaStudio; 227 this.configFactory = Factory.getInstance((PureFactory) metaStudio 228 .getATermFactory()); 229 bridge = new FactbrowserBridge(metaStudio.getATermFactory(), this); 230 popup = new DefaultPopupImpl(bridge); 231 metaStudio.connect(getName(), bridge); 232 233 addFactBrowserComponent(); 234 } 235 236 /** 237 * This method will initialize the layout and add it to the MetaStudio 238 * environment 239 * 240 * @author Renze de Vries 241 * @date 20-02-2007 242 */ 243 private void addFactBrowserComponent() { 244 final ATerm id = configFactory.getPureFactory().parse(TOOL_NAME); 245 final Event popupAction = configFactory.makeEvent_Popup(); 246 247 factBrowserWindow.addMouseListener(new MouseAdapter(id, bridge, 248 popupAction) { 249 @Override 250 public void mousePressed(MouseEvent e) { 251 factBrowserWindow.selectNodeAtPosition(e.getX(), e.getY()); 252 253 ATerm rStoreId = getSelectedRStoreId(); 254 if (rStoreId != null) { 255 setId(createEventId(rStoreId)); 256 super.mousePressed(e); 257 } 258 } 259 260 @Override 261 public void mouseClicked(MouseEvent e) { 262 if (e.getButton() == MouseEvent.BUTTON1) { 263 if (e.getClickCount() == DOUBLE_CLICK) { 264 mouseDoubleClick(e); 265 } 266 } 267 } 268 }); 269 270 component = new StudioComponentImpl("Facts", factBrowserWindow) { 271 @Override 272 public void requestClose() throws CloseAbortedException { 273 throw new CloseAbortedException(); 274 } 275 }; 276 ((StudioWithPredefinedLayout) studio).addComponent(component, 277 StudioImplWithPredefinedLayout.TOP_LEFT); 278 279 } 280 281 /** 282 * Handles the double click actions on a rstore tree node and a 283 * visualization treenode. Only the messages will be send, the data itself 284 * will not be handled here. 285 * 286 * Scenario 1: If the user double clicks on a rstore tree node a message 287 * will be send to the toolbus and requests all the facts within the rstore. 288 * 289 * Scenario 2: If the user double clicks on a fact tree node a message will 290 * be send to the toolbus to request all the possible visualizations for the 291 * given fact. 292 * 293 * @author Renze de Vries 294 * @author Bas Basten 295 * @author Anton Lycklama a Nijeholt 296 * @date 19-03-2007 297 */ 298 private void mouseDoubleClick(MouseEvent mouseEvent) { 299 DefaultMutableTreeNode selectedNode = factBrowserWindow 300 .getSelectedNode(); 301 302 if (selectedNode != null) { 303 // This is to check if the selection was on a 304 // VisualisationPlugin 305 if (dataManager.checkValidVisualisationPlugin(selectedNode)) { 306 int visPluginID = dataManager.getVisPluginID(selectedNode); 307 int factID = dataManager.getFactID(selectedNode); 308 int rstoreID = dataManager.getRStoreID(selectedNode); 309 310 // build the Aterm with the given identifiers and send it 311 ATerm term = studio.getATermFactory().make( 312 "fb-visualization-selected(<int>, <int>, <int>)", 313 rstoreID, factID, visPluginID); 314 bridge.sendEvent(term); 315 } else if (dataManager.checkValidRStoreFact(selectedNode)) { 316 } else if (dataManager.checkValidRStore(selectedNode)) { 317 } else { 318 log.warn("A node was selected which was an invalid type"); 319 } 320 } else { 321 log.warn("Double clicked but there was no node selected"); 322 } 323 } 324 325 /** 326 * @author Taeke Kooiker 327 * @date 14-08-2007 328 */ 329 public void showPopup(int RStoreId, ATerm menuList) { 330 ActionDescriptionList l = configFactory 331 .ActionDescriptionListFromTerm(menuList); 332 popup.showPopup(menuList.getFactory().makeInt(RStoreId), l); 333 } 334 335 /** 336 * @author Taeke Kooiker 337 * @date 14-08-2007 338 */ 339 public ATerm getSelectedRstoreid() { 340 ATerm rStoreId = getSelectedRStoreId(); 341 342 if (rStoreId != null) { 343 ATerm term = studio.getATermFactory().make( 344 "snd-value(selected-rstoreid(<term>))", rStoreId); 345 return term; 346 } 347 348 ATerm term = studio.getATermFactory().make( 349 "snd-value(no-rstore-selected)"); 350 return term; 351 } 352 353 /** 354 * @author Taeke Kooiker 355 * @date 15-08-2007 356 */ 357 private ATerm getSelectedRStoreId() { 358 DefaultMutableTreeNode selectedNode = factBrowserWindow 359 .getSelectedNode(); 360 361 if (selectedNode != null) { 362 while (!(selectedNode.getUserObject() instanceof RStore) 363 || selectedNode.getParent() == null) { 364 selectedNode = (DefaultMutableTreeNode) selectedNode 365 .getParent(); 366 } 367 368 if (selectedNode.getUserObject() instanceof RStore) { 369 int id = FactBrowserDataManager.getInstance().getRStoreID( 370 selectedNode); 371 return studio.getATermFactory().makeInt(id); 372 } 373 } 374 375 return null; 376 } 377 }