View Javadoc

1   /*
2    * ObjectLab, http://www.objectlab.co.uk/open is supporting JTreeMap.
3    * 
4    * Based in London, we are world leaders in the design and development 
5    * of bespoke applications for the securities financing markets.
6    * 
7    * <a href="http://www.objectlab.co.uk/open">Click here to learn more</a>
8    *           ___  _     _           _   _          _
9    *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
10   *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
11   *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
12   *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
13   *                   |__/
14   *
15   *                     www.ObjectLab.co.uk
16   *
17   * $Id: BuilderTM3.java 96 2006-11-06 20:05:53Z ekingulen $
18   * 
19   * Copyright 2006 the original author or authors.
20   *
21   * Licensed under the Apache License, Version 2.0 (the "License"); you may not
22   * use this file except in compliance with the License. You may obtain a copy of
23   * the License at
24   *
25   * http://www.apache.org/licenses/LICENSE-2.0
26   *
27   * Unless required by applicable law or agreed to in writing, software
28   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
29   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
30   * License for the specific language governing permissions and limitations under
31   * the License.
32   */
33  package net.sf.jtreemap.swing.example;
34  
35  import java.io.BufferedReader;
36  import java.io.File;
37  import java.io.FileReader;
38  import java.io.IOException;
39  import java.io.Serializable;
40  import java.text.ParseException;
41  import java.text.SimpleDateFormat;
42  import java.util.Date;
43  import java.util.Enumeration;
44  import java.util.HashMap;
45  import java.util.LinkedList;
46  import java.util.StringTokenizer;
47  import java.util.TreeSet;
48  
49  import net.sf.jtreemap.swing.DefaultValue;
50  import net.sf.jtreemap.swing.TreeMapNode;
51  import net.sf.jtreemap.swing.TreeMapNodeBuilder;
52  
53  
54  
55  /**
56   * Parse a TM3 file to build the tree. <BR>
57   * See <a href=http://www.cs.umd.edu/hcil/treemap/doc4.1/create_TM3_file.html>
58   * how to create your own TM3 data file </a> from hcil Treemap site.
59   * 
60   * @author Laurent DUTHEIL
61   */
62  public class BuilderTM3 implements Serializable {
63      /**
64       * 
65       */
66      private static final long serialVersionUID = -991159075093937695L;
67  
68      /**
69       * label "DATE" to identify Date in TM3 data file
70       */
71      public static final String DATE = "DATE";
72  
73      /**
74       * label "FLOAT" to identify float in TM3 data file
75       */
76      public static final String FLOAT = "FLOAT";
77  
78      /**
79       * label "INTEGER" to identify int in TM3 data file
80       */
81      public static final String INTEGER = "INTEGER";
82  
83      /**
84       * label "STRING" to identify String in TM3 data file
85       */
86      public static final String STRING = "STRING";
87  
88      private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
89  
90      private static final LinkedList<String> FIELD_NAMES = new LinkedList<String>();
91  
92      private static final LinkedList<String> FIELD_TYPES = new LinkedList<String>();
93  
94      private final HashMap<TreeMapNode, HashMap<String, Object>> values = new HashMap<TreeMapNode, HashMap<String, Object>>();
95  
96      private TreeMapNodeBuilder builder;
97  
98      /**
99       * Constructor
100      * 
101      * @param tm3File
102      *            tm3 file
103      * @throws IOException
104      */
105     public BuilderTM3(final File tm3File) throws IOException {
106         this.builder = new TreeMapNodeBuilder();
107         parse(new BufferedReader(new FileReader(tm3File)));
108     }
109 
110     /**
111      * Constructor
112      * 
113      * @param reader
114      *            reader associated with tm3 file
115      * @throws IOException
116      */
117     public BuilderTM3(final BufferedReader reader) throws IOException {
118         this.builder = new TreeMapNodeBuilder();
119         parse(reader);
120     }
121 
122     /**
123      * @return the number fields (ie INTEGER and FLOAT)
124      */
125     public String[] getNumberFields() {
126         final TreeSet<String> result = new TreeSet<String>();
127         for (int i = 0; i < FIELD_NAMES.size(); i++) {
128             final String type = FIELD_TYPES.get(i);
129             if (INTEGER.equals(type) || FLOAT.equals(type)) {
130                 result.add(FIELD_NAMES.get(i));
131             }
132         }
133         return result.toArray(new String[1]);
134     }
135 
136     /**
137      * get the build root.
138      * 
139      * @return the build root
140      */
141     public TreeMapNode getRoot() {
142         return this.builder.getRoot();
143     }
144 
145     /**
146      * Set the VALUES of all the JTreeMapNode with the VALUES of the fieldName.
147      * 
148      * @param fieldName
149      *            name of the field to set the VALUES
150      */
151     public void setValues(final String fieldName) {
152         if ("".equals(fieldName)) {
153             for (final TreeMapNode node : values.keySet()) {
154                 node.setValue(new DefaultValue(0));
155             }
156         } else {
157             for (final TreeMapNode node : values.keySet()) {
158                 final HashMap<String, Object> mapNodeValues = values.get(node);
159                 final Object value = mapNodeValues.get(fieldName);
160                 if (value instanceof Number) {
161                     final Number number = (Number) value;
162                     node.setValue(new DefaultValue(number.doubleValue()));
163                 } else if (value instanceof Date) {
164                     final Date date = (Date) value;
165                     node.setValue(new DefaultValue(date.getTime()));
166                 }
167             }
168         }
169     }
170 
171     /**
172      * Set the weights of all the JTreeMapNode with the VALUES of the fieldName.
173      * 
174      * @param fieldName
175      *            name of the field to set the weights
176      */
177     public void setWeights(final String fieldName) {
178         if ("".equals(fieldName)) {
179             for (final TreeMapNode node : values.keySet()) {
180                 node.setWeight(1);
181             }
182         } else {
183             for (final TreeMapNode node : values.keySet()) {
184                 final HashMap<String, Object> mapNodeValues = values.get(node);
185                 final Object value = mapNodeValues.get(fieldName);
186                 if (value instanceof Number) {
187                     final Number number = (Number) value;
188                     node.setWeight(number.doubleValue());
189                 } else if (value instanceof Date) {
190                     final Date date = (Date) value;
191                     node.setWeight(date.getTime());
192                 }
193             }
194         }
195     }
196 
197     /**
198      * @param st
199      *            StringTokenizer which contains the hierarchy path
200      * @param mapNodeValues
201      *            HashMap with fields and their VALUES
202      */
203     private void createNodes(final StringTokenizer st, final HashMap<String, Object> mapNodeValues) {
204         // read the hierarchy path
205         final LinkedList<String> hierarchyPath = new LinkedList<String>();
206         while (st.hasMoreTokens()) {
207             hierarchyPath.add(st.nextToken());
208         }
209 
210         TreeMapNode node = this.builder.getRoot();
211         if (node == null) {
212             node = this.builder.buildBranch(hierarchyPath.get(0), null);
213         }
214         for (int i = 1; i < hierarchyPath.size() - 1; i++) {
215             // looking for the child
216             boolean found = false;
217             TreeMapNode child = null;
218             for (final Enumeration iter = node.children(); iter.hasMoreElements();) {
219                 child = (TreeMapNode) iter.nextElement();
220                 if (child.getLabel().equals(hierarchyPath.get(i))) {
221                     found = true;
222                     break;
223                 }
224             }
225             if (found) {
226                 node = child;
227             } else {
228                 node = this.builder.buildBranch(hierarchyPath.get(i), node);
229             }
230         }
231 
232         // create the leaf
233         final TreeMapNode leaf = this.builder.buildLeaf(hierarchyPath.getLast(), 1, new DefaultValue(), node);
234         // each leaf is associated to their VALUES
235         values.put(leaf, mapNodeValues);
236     }
237 
238     /**
239      * @param reader The <code>BufferedReader</code>.
240      * @throws IOException
241      */
242     private void parse(final BufferedReader reader) throws IOException {
243         try {
244             String line = "";
245             // read the field names
246             line = reader.readLine();
247             StringTokenizer st = new StringTokenizer(line, "\t");
248             FIELD_NAMES.clear();
249             while (st.hasMoreTokens()) {
250                 FIELD_NAMES.add(st.nextToken());
251             }
252 
253             // read the field types
254             line = reader.readLine();
255             st = new StringTokenizer(line, "\t");
256             FIELD_TYPES.clear();
257             while (st.hasMoreTokens()) {
258                 FIELD_TYPES.add(st.nextToken());
259             }
260 
261             // read the VALUES
262             values.clear();
263             while ((line = reader.readLine()) != null) {
264                 st = new StringTokenizer(line, "\t");
265                 final HashMap<String, Object> mapNodeValues = new HashMap<String, Object>();
266                 // the VALUES are formated
267                 for (int i = 0; i < FIELD_NAMES.size(); i++) {
268                     Object value;
269                     if (FLOAT.equals(FIELD_TYPES.get(i))) {
270                         value = new Double(Double.parseDouble(st.nextToken()));
271                     } else if (INTEGER.equals(FIELD_TYPES.get(i))) {
272                         value = new Integer(Integer.parseInt(st.nextToken()));
273                     } else if (DATE.equals(FIELD_TYPES.get(i))) {
274                         try {
275                             value = DATE_FORMAT.parse(st.nextToken());
276                         } catch (final ParseException e) {
277                             value = null;
278                         }
279                     } else {
280                         value = st.nextToken();
281                     }
282                     mapNodeValues.put(FIELD_NAMES.get(i), value);
283                 }
284 
285                 // if we have not the path (the node names of parents)
286                 if (!st.hasMoreTokens()) {
287                     // we throw an exception, because we can't build the treemap
288                     throw new IOException("the file didn't contains the hierarchy path");
289                 }
290 
291                 // create the nodes
292                 createNodes(st, mapNodeValues);
293             }
294         } finally {
295             if (reader != null) {
296                 reader.close();
297             }
298         }
299     }
300 }
301 /*
302  *                 ObjectLab is supporing JTreeMap
303  * 
304  * Based in London, we are world leaders in the design and development 
305  * of bespoke applications for the securities financing markets.
306  * 
307  * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a>
308  *           ___  _     _           _   _          _
309  *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
310  *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
311  *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
312  *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
313  *                   |__/
314  *
315  *                     www.ObjectLab.co.uk
316  */