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 }