001    /* EVolve - an Extensible Software Visualization Framework
002     * Copyright (C) 2001-2002 Qin Wang
003     *
004     * This library is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Library General Public
006     * License as published by the Free Software Foundation; either
007     * version 2 of the License, or (at your option) any later version.
008     *
009     * This library is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012     * Library General Public License for more details.
013     *
014     * You should have received a copy of the GNU Library General Public
015     * License along with this library; if not, write to the
016     * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017     * Boston, MA 02111-1307, USA.
018     */
019    
020    /*
021     * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
022     */
023    
024    package EVolve.data;
025    
026    import java.awt.Color;
027    import java.io.File;
028    import java.util.ArrayList;
029    import java.util.HashMap;
030    
031    import EVolve.Scene;
032    import EVolve.exceptions.DataProcessingException;
033    import EVolve.exceptions.EVolveException;
034    import EVolve.visualization.VisualizationDefinition;
035    
036    public class DataManager implements Worker{
037        private DataSource dataSource;
038        private ElementDefinition[] definition;
039        private ReferenceLink[] link;
040        private HashMap[] entity;
041        private ElementFilter[][] elementFilter;
042        private Color color;
043        private int colorRGB;
044        private long eventCounter;
045        private long[] eventInterval;
046        private int currentInterval;
047        private boolean dataProcessed;
048        private boolean dataLoaded;
049        private int state;
050    
051    
052        public DataManager(DataSource dataSource) {
053            this.dataSource = dataSource;
054            this.eventCounter = 0;
055            dataLoaded = false;
056        }
057    
058        public void init() throws EVolveException {
059            ElementBuilder.init();
060    
061            dataSource.init();
062    
063            dataSource.startBuildDefinition();
064    
065            ArrayList definitionList = new ArrayList();
066            ElementDefinition nextDefinition = dataSource.getNextDefinition();
067            while (nextDefinition != null) {
068                definitionList.add(nextDefinition);
069                nextDefinition = dataSource.getNextDefinition();
070            }
071    
072            definition = new ElementDefinition[definitionList.size()];
073            for (int i = 0; i < definition.length; i++) {
074                definition[((ElementDefinition)(definitionList.get(i))).getType()] = (ElementDefinition)(definitionList.get(i));
075            }
076    
077            /*ArrayList[] entityList = new ArrayList[definition.length];
078            for (int i = 0; i < entityList.length; i++) {
079                entityList[i] = new ArrayList();
080            }*/
081    
082            entity = new HashMap[definition.length];
083            for (int i = 0; i < entity.length; i++) {
084                entity[i] = new HashMap();
085            }
086    
087            dataSource.startBuildEntity();
088    
089            /*Entity nextEntity = dataSource.getNextEntity();
090            while (nextEntity != null) {
091                entityList[nextEntity.getType()].add(nextEntity);
092                nextEntity = dataSource.getNextEntity();
093            }*/
094    
095            Entity nextEntity = dataSource.getNextEntity();
096            while (nextEntity != null) {
097                int type = nextEntity.getType();
098                entity[type].put(new Long(nextEntity.getId()),nextEntity);
099                nextEntity = dataSource.getNextEntity();
100            }
101    
102            /*entity = new Entity[entityList.length][];
103    
104            for (int i = 0; i < entity.length; i++) {
105                entity[i] = new Entity[entityList[i].size()];
106                for (int j = 0; j < entity[i].length; j++) {
107                    entity[i][((Entity)(entityList[i].get(j))).getId()] = (Entity)(entityList[i].get(j));
108                }
109            }*/
110    
111            // creates links
112            ArrayList list = new ArrayList();
113            for (int i = 0; i < definition.length; i++) {
114                for (int j = 0; j < definition[i].getFieldDefinition().length; j++) {
115                    if ((definition[i].getFieldDefinition()[j].getReference() != -1) &&
116                        (definition[i].getFieldDefinition()[j].getReference() != i)) {
117                        list.add(new ReferenceLink(definition[i].getFieldDefinition()[j].getName(), i,
118                                 j, definition[i].getFieldDefinition()[j].getReference(),
119                                 definition[i].getFieldDefinition()[j].getDescription(),
120                                 definition[i].getFieldDefinition()[j].getProperties()));
121                    }
122                }
123            }
124    
125            int head = 0;
126            int tail = list.size();
127            int initSize = list.size();
128    
129            while (head < tail) {
130                for (int i = head; i < tail; i++) {
131                    for (int j = 0; j < initSize; j++) {
132                        ReferenceLink from = (ReferenceLink)(list.get(j));
133                        ReferenceLink to = (ReferenceLink)(list.get(i));
134                        if ((from.getTargetType() == to.getSourceType()) && (from.getSourceType() != to.getTargetType())) {
135                            list.add(new ReferenceLink(from, to));
136                        }
137                    }
138                }
139                head = tail;
140                tail = list.size();
141            }
142    
143            link = new ReferenceLink[list.size()];
144            for (int i = 0; i < link.length; i++) {
145                link[i] = (ReferenceLink)(list.get(i));
146            }
147        }
148    
149        public void sendEvents() throws DataProcessingException {
150    
151            state = Worker.STATE_RUNNING;
152    
153            Selection[] selection = Scene.getFilter().getSelection();
154            Selection activeSelection = Scene.getFilter().getActiveSelection();
155            dataProcessed = false;
156            if (activeSelection != null) {
157                eventInterval = new long[4];
158                eventInterval[0] = 0;
159                eventInterval[1] = activeSelection.getStart();
160                eventInterval[2] = activeSelection.getEnd();
161                eventInterval[3] = Integer.MAX_VALUE;
162            } else {
163                eventInterval = new long[2];
164                eventInterval[0] = 0;
165                eventInterval[1] = Integer.MAX_VALUE;
166            }
167    
168            elementFilter = new ElementFilter[eventInterval.length - 1][definition.length];
169            for (int i = 0; i < elementFilter.length; i++) {
170                boolean isIncluded = activeSelection == null ? true : false;
171                for (int j = 0; j < selection.length; j++) {
172                    if ((selection[j] == activeSelection)&&
173                        (((selection[j].getStart() >= eventInterval[i])&&(selection[j].getEnd() <= eventInterval[i+1]))
174                         ||((selection[j].getStart()==eventInterval[i])&&(eventInterval[i]==0)))) {
175                        isIncluded = true;
176                        break;
177                    }
178                }
179    
180                if (isIncluded)
181                {
182                    ArrayList list = new ArrayList();
183                    if (activeSelection != null) list.add(activeSelection);
184                    for (int j = 0; j < selection.length; j++) {
185                        if ((selection[j].getColor()!=null) && (selection[j] != activeSelection)) {
186                            list.add(selection[j].specialClone());
187                        }
188                    }
189                    Selection[] tempSelection = new Selection[list.size()];
190                    for (int j = 0; j < tempSelection.length; j++) {
191                        tempSelection[j] = (Selection)(list.get(j));
192                    }
193    
194                    for (int j = 0; j < definition.length; j++) {
195                        if (Scene.getVisualizationManager().getVisualizationType().indexOf("" + j + "") != -1) {
196                            elementFilter[i][j] = new ElementFilter(definition[j], tempSelection);
197                        } else {
198                            elementFilter[i][j] = null;
199                        }
200                    }
201                } else {
202                    elementFilter[i] = null;
203                }
204    
205            }
206    
207            currentInterval = 0;
208    
209            dataSource.startBuildEvent();
210            eventCounter = 0;
211    
212            Event nextEvent = dataSource.getNextEvent();
213            while (nextEvent != null) {
214    
215                if (state == STATE_PAUSING) {
216                    try {
217                        synchronized(this) {
218                            this.state = STATE_PAUSED;
219                            wait();
220                        }
221                        state = STATE_RUNNING;
222                    } catch (InterruptedException e) {
223                        if (state == STATE_STOPPING) {
224                            state = STATE_STOPPED;
225                            throw new DataProcessingException("Data processing cancelled by the user.");
226                        }
227                    }
228                } else if (state == STATE_STOPPING) {
229                    state = STATE_STOPPED;
230                    throw new DataProcessingException("Data processing cancelled by the user.");
231                }
232    
233    
234                if ((elementFilter[currentInterval] != null) && (elementFilter[currentInterval][nextEvent.getType()] != null)) {
235                    color = elementFilter[currentInterval][nextEvent.getType()].getColor(nextEvent);
236                    if (color != null) {
237                        colorRGB = color.getRGB();
238                        Scene.getVisualizationManager().receiveEvent(nextEvent);
239                    }
240                }
241    
242                if (eventCounter == eventInterval[currentInterval + 1]) {
243                    currentInterval++;
244                }
245    
246                eventCounter++;
247                nextEvent = dataSource.getNextEvent();
248            }
249            dataProcessed = true;
250            state = STATE_FINISHED;
251        }
252    
253        public HashMap[] getEntity() {
254            return entity;
255        }
256    
257        public ElementDefinition[] getElementDefinition() {
258            return definition;
259        }
260    
261        public ElementDefinition[] getElementDefinition(VisualizationDefinition visualizationDefinition) {
262            ArrayList list = new ArrayList();
263            for (int i = 0; i < definition.length; i++) {
264                boolean add = true;
265                for (int j = 0; j < visualizationDefinition.getDimensionDefinition().length; j++) {
266                    DataFilter[] temp = getDataFilter(definition[i], visualizationDefinition.getDimensionDefinition()[j].getProperty());
267                    if (temp.length == 0) {
268                        add = false;
269                        break;
270                    }
271                }
272                if (add) {
273                    list.add(definition[i]);
274                }
275            }
276    
277            ElementDefinition[] returnVal = new ElementDefinition[list.size()];
278            for (int i = 0; i < returnVal.length; i++) {
279                returnVal[i] = (ElementDefinition)(list.get(i));
280            }
281    
282            return returnVal;
283        }
284    
285        public DataFilter[] getDataFilter(ElementDefinition subjectDefinition, String property) {
286            ArrayList list = new ArrayList();
287            FieldDefinition fd;
288            boolean nonLinkField = true;
289    
290            for (int i = 0; i<link.length; i++) {
291                if (link[i].hasProperty(property)) {
292                    if (link[i].getSourceType() == subjectDefinition.getType()) {
293                        list.add(new DataFilter(link[i].getName(), link[i].getSourceIndex(), link[i], link[i].getDescription(),null));
294                    }
295                    nonLinkField = false;
296                }
297            }
298    
299            if (nonLinkField) {
300                for (int i = 0; i < subjectDefinition.getFieldDefinition().length; i++) {
301                    fd = subjectDefinition.getFieldDefinition()[i];
302                    if (subjectDefinition.getFieldDefinition()[i].hasProperty(property)) {
303                        list.add(new DataFilter(subjectDefinition.getFieldDefinition()[i].getName(), i,
304                                                null, subjectDefinition.getFieldDefinition()[i].getDescription(),fd.getProperties()));
305                    }
306                }
307            }
308    
309            DataFilter[] returnVal = new DataFilter[list.size()];
310            for (int i = 0; i < returnVal.length; i++) {
311                returnVal[i] = (DataFilter)(list.get(i));
312            }
313    
314            return returnVal;
315        }
316    
317        public Color getColor() {
318            return color;
319        }
320    
321        public int getColorRGB() {
322            return colorRGB;
323        }
324    
325        public long getEventCounter() {
326            return eventCounter;
327        }
328    
329        public ReferenceLink[] getReferenceLink() {
330            return link;
331        }
332    
333        public boolean isCompleted() {
334            return dataProcessed;
335        }
336    
337        public String getDatasourceName() {
338            String fileName = dataSource.getFileName();
339    
340            if (fileName == null)
341                fileName = "No Data";
342            else
343                fileName = fileName.substring(fileName.lastIndexOf(File.separatorChar)+1);
344    
345            return dataSource.getName()+" - "+fileName;
346        }
347    
348        public boolean isDataLoaded() {
349            return dataLoaded;
350        }
351    
352        public void setDataLoaded(boolean loaded) {
353            dataLoaded = loaded;
354        }
355    
356        public DataSource getDataSource() {
357            return dataSource;
358        }
359    
360        public synchronized void resume() {
361            notifyAll();
362        }
363    
364        public synchronized void pause() {
365            if (state == STATE_RUNNING) {
366                state = STATE_PAUSING;
367            }
368        }
369    
370        public synchronized void stop() {
371            switch (state) {
372                case STATE_NOT_STARTED:
373                case STATE_STOPPED:
374                case STATE_FINISHED:
375                    break;
376                default:
377                    state = STATE_STOPPING;
378                    break;
379            }
380        }
381    
382        public synchronized long getCurrentProgress() {
383            return eventCounter;
384        }
385    
386        public synchronized long getMaxProgress() {
387            return dataSource.getTotalNumberOfEvents();
388        }
389    
390        public synchronized int getCurrentState() {
391            return state;
392        }
393    
394        public synchronized void start() {
395            state = STATE_RUNNING;
396        }
397    
398        public void join() throws InterruptedException {
399        }
400    
401        public void resetState() {
402            state = Worker.STATE_NOT_STARTED;
403        }
404    }