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.visualization;
025    
026    import java.util.*;
027    import EVolve.Scene;
028    import EVolve.data.Element;
029    import EVolve.data.Entity;
030    import EVolve.data.EntityComparator;
031    import EVolve.data.EntityDefinition;
032    import EVolve.data.LexicalComparator;
033    import EVolve.data.Selection;
034    import EVolve.data.ValueComparator;
035    import EVolve.exceptions.NoDataPlotException;
036    import EVolve.util.HelperFuncs;
037    import EVolve.util.Sorter;
038    
039    public class ReferenceDimension extends Dimension implements Cloneable{
040        private ArrayList comparatorList;
041        private int currentOrder;
042        private int[] order;
043        private int [] orderBfUnify;
044        private Entity[] entity;
045        private HashSet linkedEntity;
046        private int selectedIndex;
047        private int entityNumber;
048        private HashMap Int2Entity, EntityName2Int;
049        private Sorter sorter;
050        private ArrayList availableSortScheme;
051        private boolean sortable;
052    
053        public ReferenceDimension() {
054            comparatorList = new ArrayList();
055            linkedEntity = null;
056            selectedIndex = 0;
057            entityNumber = -1;
058            Int2Entity = new HashMap();
059            EntityName2Int = new HashMap();
060            orderBfUnify = null;
061            availableSortScheme = new ArrayList();
062            availableSortScheme.add("Lexical");
063            availableSortScheme.add("Temporal");
064            sortable = false;
065        }
066    
067        public ReferenceDimension(boolean sortable) {
068            this();
069            this.sortable = sortable;
070        }
071    
072        public int getMaxEntityNumber() {
073            return Scene.getDataManager().getEntity()[dataFilter.getTargetType()].size();
074        }
075    
076        public int getEntityNumber() {
077            return entity==null ? -1 : entity.length;
078        }
079    
080        public long getField(Element element) {
081            long returnVal = dataFilter.getData(element);
082            Integer mappedId = findMappedId(returnVal);
083    
084            if (order[mappedId.intValue()] == Integer.MAX_VALUE) {
085                order[mappedId.intValue()] = currentOrder;
086                currentOrder++;
087            }
088            return mappedId.intValue();
089        }
090    
091        public void preVisualize() {
092            currentOrder = 0;
093            EntityName2Int.clear();
094            Int2Entity.clear();
095            order = new int[getMaxEntityNumber()];
096            for (int i = 0; i < order.length; i++) {
097                order[i] = Integer.MAX_VALUE;
098            }
099        }
100    
101        public void restore() {
102            order = new int[getMaxEntityNumber()];
103            for (int i = 0; i < order.length; i++) {
104                if (i<currentOrder)
105                    order[i] = i;
106                else
107                    order[i] = Integer.MAX_VALUE;
108            }
109            linkedEntity = null;
110    
111            ArrayList tobeDel = new ArrayList();
112            Iterator it = Int2Entity.keySet().iterator();
113            while (it.hasNext()) {
114                Integer key = (Integer)it.next();
115                if (key.intValue() >= currentOrder) {
116                    tobeDel.add(key);
117                }
118            }
119            for (int i=0; i<tobeDel.size(); i++) {
120                Int2Entity.remove(tobeDel.get(i));
121            }
122    
123            tobeDel.clear();
124            it = EntityName2Int.keySet().iterator();
125            while (it.hasNext()) {
126                Object key = it.next();
127                Integer value = (Integer)EntityName2Int.get(key);
128                if (value.intValue() >= currentOrder) {
129                    tobeDel.add(key);
130                }
131            }
132            for (int i=0; i<tobeDel.size(); i++) {
133                EntityName2Int.remove(tobeDel.get(i));
134            }
135        }
136    
137        public void visualize() throws NoDataPlotException{
138    
139            if (linkedEntity == null) {
140                entity = new Entity[currentOrder];
141    
142                for (int i = 0; i < order.length; i++) {
143                    if (order[i] != Integer.MAX_VALUE) {
144                        entity[order[i]] = (Entity)Int2Entity.get(new Integer(i));
145                    }
146                }
147            } else { // unified reference dimension
148                int free = currentOrder;
149                entityNumber = currentOrder;
150                entity = new Entity[linkedEntity.size()];
151    
152                order = new int[linkedEntity.size()];
153                Iterator it = linkedEntity.iterator();
154                while (it.hasNext()) {
155                    Entity aEntity = (Entity)it.next();
156                    Integer mappedId = (Integer)EntityName2Int.get(aEntity.getName());
157                    if (mappedId != null) {
158                        order[mappedId.intValue()] = mappedId.intValue();
159                        entity[order[mappedId.intValue()]] = aEntity;
160                    } else {
161                        Int2Entity.put(new Integer(free), aEntity);
162                        EntityName2Int.put(aEntity.getName(), new Integer(free));
163                        order[free] = Integer.MAX_VALUE;
164                        entity[free] = aEntity;
165                        free++;
166                    }
167                }
168            }
169    
170            comparatorList.clear();
171            comparatorList.add(new LexicalComparator());
172            comparatorList.add(new ValueComparator("Temporal", true, order, EntityName2Int));
173            ArrayList entityComparatorList = ((EntityDefinition)(Scene.getDataManager().getElementDefinition()[dataFilter.getTargetType()])).getComparator();
174            for (int i = 0; i < entityComparatorList.size(); i++) {
175                comparatorList.add(entityComparatorList.get(i));
176            }
177    
178            if (selectedIndex < comparatorList.size())
179                sorter = new Sorter(entity, (EntityComparator)(comparatorList.get(selectedIndex)));
180    
181            // we generate an exception on purpose for empty image
182            if (entity.length == 0) throw new NoDataPlotException();
183        }
184    
185        public Entity getEntity(int index) {
186            int newMappedId = (sorter == null) ? index : sorter.getSource(index);
187    
188            if ((newMappedId < currentOrder)&&(Int2Entity.containsKey(new Integer(newMappedId)))) {
189                return (Entity)Int2Entity.get(new Integer(newMappedId));
190            }
191    
192            return null;
193        }
194    
195        public ArrayList getComparator() {
196            return comparatorList;
197        }
198    
199        public void selectComparator(int selectedIndex) {
200            sorter = new Sorter(entity, (EntityComparator)(comparatorList.get(selectedIndex)));
201            this.selectedIndex = selectedIndex;
202        }
203    
204        public void selectComparator(String comparatorName) {
205            for (int i=0; i<comparatorList.size(); i++) {
206                if (comparatorName.equals(((EntityComparator)comparatorList.get(i)).getName())) {
207                    selectComparator(i);
208                }
209            }
210        }
211    
212        public void addComparator(EntityComparator comparator) {
213            boolean found = false;
214            for (int i=0; i<comparatorList.size(); i++) {
215                if (((EntityComparator)comparatorList.get(i)).getName().equals(comparator.getName()))
216                    found = true;
217            }
218            if (!found) comparatorList.add(comparator);
219        }
220    
221        public int getSortedIndex(int mappedId) {
222            if (order[mappedId] == Integer.MAX_VALUE) {
223                return -1;
224            } else {
225                return sorter.getTarget(order[mappedId]);
226            }
227        }
228    
229        public int getOriginMappedId(int sortedId) {
230            int mappedId = sorter.getSource(sortedId);
231            return mappedId;
232        }
233    
234        public void makeSelection(String name, int sourceType, int[] selection) {
235            if (selection.length != 0) {
236                ArrayList temp = new ArrayList();
237                for (int i = 0; i < selection.length; i++) {
238                    Entity aEntity = getEntity(selection[i]);
239                    if (aEntity!=null) temp.add(aEntity);
240                }
241    
242                long[] selected = new long[temp.size()];
243                for (int i = 0; i < temp.size(); i++) {
244                    selected[i] = ((Entity)temp.get(i)).getId();
245                }
246                Scene.getFilter().addSelection(new Selection(name,sourceType,dataFilter.getTargetType(),dataFilter.getName(),
247                                                             selected, 0, Long.MAX_VALUE,null));
248            }
249        }
250    
251        public void makeSelection(String name, int sourceType, int[] selection, long start, long end, ArrayList timeMap) {
252            if (selection.length != 0) {
253                ArrayList temp = new ArrayList();
254                for (int i = 0; i < selection.length; i++) {
255                    Entity aEntity = getEntity(selection[i]);
256                    if (aEntity!=null) temp.add(aEntity);
257                }
258    
259                long[] selected = new long[temp.size()];
260                for (int i = 0; i < temp.size(); i++) {
261                    selected[i] = ((Entity)temp.get(i)).getId();
262                }
263                Scene.getFilter().addSelection(new Selection(name, sourceType, dataFilter.getTargetType(),
264                                                             dataFilter.getName(),selected, start, end, timeMap));
265            }
266        }
267    
268        public Entity[] getEntities() {
269            return entity;
270        }
271    
272        public void linkEntities(HashSet linkedEntity) {
273            if (this.linkedEntity != null)
274                restore();
275            this.linkedEntity = linkedEntity;
276        }
277    
278        public void clearEntityMap() {
279            linkedEntity = null;
280            entity = null;
281            entityNumber = -1;
282        }
283    
284        public int getSelectedComparatorIndex() {
285            return selectedIndex;
286        }
287    
288        public String getSelectedComparatorName() {
289            if (comparatorList.size() == 0) {
290                return new LexicalComparator().getName();
291            }
292            return ((EntityComparator)comparatorList.get(selectedIndex)).getName();
293        }
294    
295        public int[] getOrdering() {
296            if (orderBfUnify == null)
297                return order;
298            else
299                return orderBfUnify;
300        }
301    
302        public void updateOrdering(int[] newOrder) {
303            if (orderBfUnify == null)
304                orderBfUnify = order;
305            order = newOrder;
306        }
307    
308        public int getEntityNumberBeforeLink() {
309            return entityNumber;
310        }
311    
312        public HashMap getEntityName2IntMap() {
313            return EntityName2Int;
314        }
315    
316        public HashMap getInt2EntityMap() {
317            return Int2Entity;
318        }
319    
320        public Entity getEntityFromInt(int mappedId) {
321            Integer key = new Integer(mappedId);
322            if (Int2Entity.containsKey(key)) {
323                return (Entity)Int2Entity.get(key);
324            } else
325                return null;
326        }
327    
328        private Integer findMappedId(long entityId) {
329            Long value = new Long(entityId);
330            Entity entity = (Entity)Scene.getDataManager().getEntity()[dataFilter.getTargetType()].get(value);
331    
332            if (EntityName2Int.containsKey(entity.getName())) {
333                return (Integer)EntityName2Int.get(entity.getName());
334            } else {
335                Integer mappedId = new Integer(Int2Entity.size());
336                Int2Entity.put(mappedId,entity);
337                EntityName2Int.put(entity.getName(),mappedId);
338                return mappedId;
339            }
340        }
341    
342        public ArrayList getAvailableSortSchemes() {
343    
344            ArrayList entityComparatorList = ((EntityDefinition)(Scene.getDataManager().getElementDefinition()[dataFilter.getTargetType()])).getComparator();
345    
346            ArrayList returnVal = new ArrayList();
347            for (int i=0; i<availableSortScheme.size(); i++) {
348                returnVal.add(availableSortScheme.get(i));
349            }
350            for (int i = 0; i < entityComparatorList.size(); i++) {
351                String newScheme = ((EntityComparator)entityComparatorList.get(i)).getName();
352                if (!availableSortScheme.contains(newScheme))
353                    returnVal.add(newScheme);
354            }
355    
356            return returnVal;
357        }
358    
359        public void addSortSchemes(String newScheme) {
360            if (!availableSortScheme.contains(newScheme))
361                availableSortScheme.add(newScheme);
362        }
363    
364        public boolean isSortable() {
365            return sortable;
366        }
367    
368        public Object clone() {
369            ReferenceDimension o = (ReferenceDimension) super.clone();
370            o.comparatorList = (ArrayList)comparatorList.clone();
371            o.comparatorList.clear();
372            for (int i=0; i<comparatorList.size(); i++) {
373                o.comparatorList.add(((EntityComparator)comparatorList.get(i)).clone());
374            }
375            o.entity = null;
376            if (entity != null) {
377                o.entity = new Entity[entity.length];
378                for (int i=0; i<o.entity.length; i++)
379                    o.entity[i] = entity[i];
380            }
381            o.linkedEntity = HelperFuncs.cloneHashSet(linkedEntity);
382            o.Int2Entity = HelperFuncs.cloneHashMap(Int2Entity);
383            o.EntityName2Int = HelperFuncs.cloneHashMap(EntityName2Int);
384    
385            o.order = null;
386            if (order != null) {
387                o.order = new int[order.length];
388                for (int i=0; i<order.length; i++) {
389                    o.order[i] = order[i];
390                }
391            }
392    
393            o.sorter = (sorter == null) ? null : (Sorter)sorter.clone();
394            o.sortable = sortable;
395            return o;
396        }
397    }