001    package nl.cwi.sen1.visbase.factbrowser.data;
002    
003    import java.util.ArrayList;
004    import java.util.Iterator;
005    
006    import javax.swing.tree.DefaultMutableTreeNode;
007    
008    import nl.cwi.sen1.relationstores.types.RType;
009    
010    /**
011     * This class is the dataManager for the different visualizationPlugins and the
012     * RStoreFactTypes (like <str,str>) which are registered. It also caches the
013     * different visualisationPlugins and RStoreFactTypes.
014     * 
015     * <b>Relational representation of in memory data structure</b> This
016     * dataManager holds an in memory representation of the RStore with it's
017     * children facts.
018     * 
019     * Also it tracks all different types of RStoreFactTypes which are sent. Every
020     * visualisationPlugin which is sent should be coupled with a RStoreFactType.
021     * When a visualisationPlugin registers itself to a cached or new RStoreFactType
022     * a signal is sent to all children facts of the RStores which are
023     * RStoreFactType compatible.
024     * 
025     * @author Renze de Vries
026     * @date 14-02-2007
027     * 
028     */
029    
030    public class FactBrowserDataManager {
031        private static FactBrowserDataManager dataManagerInstance;
032    
033        private ArrayList<RStoreFactType> factTypes;
034    
035        private ArrayList<VisualisationPlugin> visPlugins;
036    
037        /**
038         * Default constructor where the caching containers for the FactTypes and
039         * the Plugins are initialized. This is also private so it can only be
040         * instantiated from within this class.
041         * 
042         * @author Renze de Vries
043         * @date 14-02-2007
044         */
045        private FactBrowserDataManager() {
046            factTypes = new ArrayList<RStoreFactType>();
047            visPlugins = new ArrayList<VisualisationPlugin>();
048        }
049    
050        /**
051         * This method makes it possible to centrally access the dataManager and
052         * only create it once. This is the method which enforces the singleton
053         * pattern.
054         * 
055         * @author Renze de Vries
056         * @date 22-02-2007
057         * 
058         * @return The instance of the DataManager
059         */
060        public static FactBrowserDataManager getInstance() {
061            if (dataManagerInstance == null) {
062                dataManagerInstance = new FactBrowserDataManager();
063            }
064    
065            return dataManagerInstance;
066        }
067    
068        /**
069         * This method makes it possible to reset all the elements so we can if
070         * nessecary start with a clean in memory list.
071         * 
072         * @author Renze de Vries
073         * @date 22-02-2007
074         */
075        public void resetDataManager() {
076            factTypes.clear();
077            visPlugins.clear();
078        }
079    
080        /**
081         * This method is a method which directs the creation of a new Visualisation
082         * plugin and couples it to the different FactTypes
083         * 
084         * @param visNewPlugin
085         *            This is the new Visualisation Plugin to be created
086         * @param visFactType
087         *            This is the FactType this plugin can display
088         * 
089         * @author Renze de Vries
090         * @date 14-02-2007
091         */
092        public void createVisualisation(VisualisationPlugin visNewPlugin,
093                RStoreFactType visFactType) {
094            // This method call is to get create the plugin in cache
095            // or if not already present get the cached version
096            visNewPlugin = addVisualisation(visNewPlugin);
097    
098            // Now we must couple the plugin to the FactType so call the method
099            // which will do this.
100            coupleVisualisation(visNewPlugin, visFactType);
101        }
102    
103        /**
104         * This method is to add the Visualisation Plugin to the cache or if already
105         * present give the already present VisualisationPlugin instance back
106         * 
107         * @param visNewPlugin
108         *            This is the Visualisation Plugin we want to add
109         * @return the instance of the Visualisation plugin which is or newly
110         *         created or from the cache
111         * 
112         * @author Renze de Vries
113         * @date 14-02-2007
114         */
115        private VisualisationPlugin addVisualisation(
116                VisualisationPlugin visNewPlugin) {
117            Iterator<VisualisationPlugin> iterator = visPlugins.iterator();
118            while (iterator.hasNext()) {
119                VisualisationPlugin visPlugin = iterator.next();
120                if (visPlugin.getPluginId() == visNewPlugin.getPluginId()) {
121                    return visPlugin;
122                }
123            }
124    
125            visPlugins.add(visNewPlugin);
126    
127            return visNewPlugin;
128        }
129    
130        /**
131         * This method couples the visualisationPlugin to the nessecary
132         * RStoreFactTypes. When this happens the facts which are a member of the
133         * RStoreFactType will be notified.
134         * 
135         * @param visPlugin
136         *            The VisualisationPlugin to add to the specific FactType
137         * @param visFactType
138         *            The FactType this visualisationPlugin applies to
139         * 
140         * @author Renze de Vries
141         * @date 14-02-2007
142         */
143        private void coupleVisualisation(VisualisationPlugin visPlugin,
144                RStoreFactType visFactType) {
145    
146            // Go through all the RStoreFactTypes
147            for (RStoreFactType factType : factTypes) {
148                // If the RStoreFactType of the VisualisationPlugin matches that of
149                // the cached RStoreFactType add the VisualisationPlugin tot it.
150                if (factType == visFactType) {
151                    factType.addVisualisationPlugin(visPlugin);
152                }
153            }
154        }
155    
156        /**
157         * This method is to register an RStoreFactType. It will check if the
158         * RStoreFactType was already in the cache and if so return that instance.
159         * If not present create such an RStoreFactType and register it in the cache
160         * and return the created instance.
161         * 
162         * @param newFactType
163         *            The FactType we want to add
164         * 
165         * @author Renze de Vries
166         * @date 14-02-2007
167         */
168        public RStoreFactType addFactType(String newType) {
169    
170            // Use the Java foreach iterator to look at all already cached
171            // RStoreFactTypes
172            for (RStoreFactType factType : factTypes) {
173    
174                // If the RStoreFactType is already present return that instance.
175                if (factType.getFactType().equalsIgnoreCase(newType)) {
176                    return factType;
177                }
178            }
179    
180            // If the FactType was not already in the container we can now add it
181            RStoreFactType newFactType = new RStoreFactType(newType);
182            factTypes.add(newFactType);
183    
184            return newFactType;
185        }
186    
187        /**
188         * This method checks if the given selectedNode from the visual
189         * factBrowser tree was really a visualisationPlugin.
190         * 
191         * @param selectedNode The selectedNode from the visual tree
192         * @return true if it was a visualisation plugin else false
193         * 
194         * @author Renze de Vries
195         * @date 12-03-2007
196         */
197        public boolean checkValidVisualisationPlugin(
198                DefaultMutableTreeNode selectedNode) {
199            if (selectedNode.getUserObject() instanceof VisualisationPlugin) {
200                return true;
201            }
202                    return false;
203        }
204    
205        /**
206         * This method checks if the given selectedNode from the visual
207         * factBrowser tree was a RStoreFact.
208         * 
209         * @param selectedNode The selectedNode from the visual Tree
210         * @return true if it was a RStoreFact plugin else false
211         * 
212         * @author Renze de Vries
213         * @date 12-03-2007
214         */
215        public boolean checkValidRStoreFact(DefaultMutableTreeNode selectedNode) {
216            if (selectedNode instanceof RStoreFact) {
217                return true;
218            }
219                    return false;
220        }
221    
222        public boolean checkValidRStore(DefaultMutableTreeNode selectedNode) {
223            if (selectedNode.getUserObject() instanceof RStore) {
224                return true;
225            }
226                    return false;            
227        }
228        
229        /**
230         * This method gets the Fact Identifier of a RStoreFact. It does this
231         * by a given selected visualisationPlugin and gathers from the in memory
232         * tree the identifier.
233         * 
234         * @param selectedNode The selectedNode from the visualTree
235         * @return The RStoreFact Identifier
236         * 
237         * @author Renze de Vries
238         * @date 12-03-2007
239         */
240        public int getFactID(DefaultMutableTreeNode selectedNode) {
241            //check if the given selected node is really a visualisation Plugin
242            if (checkValidVisualisationPlugin(selectedNode)) {
243                RStoreFact rstoreFact = (RStoreFact) selectedNode.getParent();
244    
245                return rstoreFact.getFactId();
246            }
247            
248            //if the selectednode was not a visualisationPlugin return -1
249            return -1;
250        }
251    
252        /**
253         * This method gets the RStore Identifier based on a selected VisualisationPlugin
254         * from the visual tree. It gathers the identifiers from the in memory tree.
255         * 
256         * @param selectedNode The selectedNode from the visualTree
257         * @return The RStore identifier
258         * 
259         * @author Renze de Vries
260         * @date 12-03-2007
261         * 
262         * TODO: This method needs refactoring. The comments do not match the intended
263         * purpose of this method. 
264         */
265        public int getRStoreID(DefaultMutableTreeNode selectedNode) {
266            //for this to work it must be a visualisationPlugin
267            if (checkValidVisualisationPlugin(selectedNode)) {
268                
269                //get from the visual tree the parent of the selectedNode (VisualisationPlugin)
270                //this parent (RStoreFact) get the parent which is a RStore.
271                DefaultMutableTreeNode rstoreNode = (DefaultMutableTreeNode) selectedNode
272                        .getParent().getParent();
273    
274                RStore rstore = (RStore) rstoreNode.getUserObject();
275                return rstore.getRstoreId();
276            }
277            else if (checkValidRStore(selectedNode)) {
278                RStore rstore = (RStore) selectedNode.getUserObject();
279                return rstore.getRstoreId();
280            }
281            
282            //if the selectednode was not a visualisationPlugin return -1
283            return -1;
284        }
285    
286        /**
287         * This method returns the identifier of the visualisationPlugin.
288         * 
289         * @param selectedNode The given selectedNode from the visual tree
290         * @return The identifier of the visualisationPlugin
291         * 
292         * @author Renze de Vries
293         * @date 12-03-2007
294         */
295        public int getVisPluginID(DefaultMutableTreeNode selectedNode) {
296            //check if the selectedNode was realy a visualisationPlugin
297            if (checkValidVisualisationPlugin(selectedNode)) {
298                VisualisationPlugin visPlugin = (VisualisationPlugin) selectedNode
299                        .getUserObject();
300    
301                return visPlugin.getPluginId();
302            }
303            
304            //if the selectednode was not a visualisationPlugin return -1
305            return -1;
306        }
307    
308        /**
309         * This method returns the RType of a selectedNode from the visualtree.
310         * For this to work it must be a selected RStoreFact.
311         * 
312         * @param selectedNode The selectedNode from the visual tree
313         * @return The RType of the RStoreFact
314         */
315        public RType getFactRType(DefaultMutableTreeNode selectedNode) {
316            //check if the given selectedNode is really a RStoreFact
317            if(checkValidRStoreFact(selectedNode))
318            {
319                RStoreFact rstoreFact = (RStoreFact) selectedNode;
320                
321                return rstoreFact.getRType();
322            }
323            
324            //if the given selectedNode was not a RStoreFact return null
325            return null;
326        }
327    }