1   
2   
3   
4   
5   
6   
7   
8   package org.dom4j.swing;
9   
10  import java.io.Serializable;
11  import java.util.ArrayList;
12  import java.util.HashMap;
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.Map;
16  
17  import org.dom4j.Document;
18  import org.dom4j.DocumentHelper;
19  import org.dom4j.Element;
20  import org.dom4j.XPath;
21  
22  import org.jaxen.VariableContext;
23  
24  /***
25   * <p>
26   * <code>XMLTableDefinition</code> represents a table definition based on
27   * XPath expression evaluated on an XML document.
28   * </p>
29   * 
30   * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
31   * @version $Revision: 1.8 $
32   */
33  public class XMLTableDefinition implements Serializable, VariableContext {
34      /*** Holds value of property rowXPath. */
35      private XPath rowXPath;
36  
37      /*** The columns to display in this table */
38      private List columns = new ArrayList();
39  
40      /*** integer index array cache */
41      private XMLTableColumnDefinition[] columnArray;
42  
43      /*** name index cache */
44      private Map columnNameIndex;
45  
46      /*** for cross-row variables */
47      private VariableContext variableContext;
48  
49      /*** stores the current row value for the variableContext */
50      private Object rowValue;
51  
52      public XMLTableDefinition() {
53      }
54  
55      /***
56       * Loads an XML table definition from an XML definition document
57       * 
58       * @param definition
59       *            DOCUMENT ME!
60       * 
61       * @return DOCUMENT ME!
62       */
63      public static XMLTableDefinition load(Document definition) {
64          return load(definition.getRootElement());
65      }
66  
67      /***
68       * Loads an XML table definition from an XML definition document
69       * 
70       * @param definition
71       *            DOCUMENT ME!
72       * 
73       * @return DOCUMENT ME!
74       */
75      public static XMLTableDefinition load(Element definition) {
76          XMLTableDefinition answer = new XMLTableDefinition();
77          answer.setRowExpression(definition.attributeValue("select"));
78  
79          for (Iterator iter = definition.elementIterator("column"); iter
80                  .hasNext();) {
81              Element element = (Element) iter.next();
82              String expression = element.attributeValue("select");
83              String name = element.getText();
84              String typeName = element.attributeValue("type", "string");
85              String columnXPath = element.attributeValue("columnNameXPath");
86              int type = XMLTableColumnDefinition.parseType(typeName);
87  
88              if (columnXPath != null) {
89                  answer.addColumnWithXPathName(columnXPath, expression, type);
90              } else {
91                  answer.addColumn(name, expression, type);
92              }
93          }
94  
95          return answer;
96      }
97  
98      public Class getColumnClass(int columnIndex) {
99          return getColumn(columnIndex).getColumnClass();
100     }
101 
102     public int getColumnCount() {
103         return columns.size();
104     }
105 
106     /***
107      * DOCUMENT ME!
108      * 
109      * @param columnIndex
110      *            DOCUMENT ME!
111      * 
112      * @return the static column name. This is used if there is no
113      *         columnNameXPath
114      */
115     public String getColumnName(int columnIndex) {
116         return getColumn(columnIndex).getName();
117     }
118 
119     /***
120      * DOCUMENT ME!
121      * 
122      * @param columnIndex
123      *            DOCUMENT ME!
124      * 
125      * @return the XPath expression used to evaluate the value of cells in this
126      *         column
127      */
128     public XPath getColumnXPath(int columnIndex) {
129         return getColumn(columnIndex).getXPath();
130     }
131 
132     /***
133      * DOCUMENT ME!
134      * 
135      * @param columnIndex
136      *            DOCUMENT ME!
137      * 
138      * @return the XPath expresssion used to create the column name, if there is
139      *         one or null if there is no XPath expression to name the column.
140      */
141     public XPath getColumnNameXPath(int columnIndex) {
142         return getColumn(columnIndex).getColumnNameXPath();
143     }
144 
145     public synchronized Object getValueAt(Object row, int columnIndex) {
146         XMLTableColumnDefinition column = getColumn(columnIndex);
147         Object answer = null;
148 
149         synchronized (this) {
150             this.rowValue = row;
151             answer = column.getValue(row);
152             this.rowValue = null;
153         }
154 
155         return answer;
156     }
157 
158     public void addColumn(String name, String expression) {
159         addColumn(name, expression, XMLTableColumnDefinition.OBJECT_TYPE);
160     }
161 
162     public void addColumn(String name, String expression, int type) {
163         XPath xpath = createColumnXPath(expression);
164         addColumn(new XMLTableColumnDefinition(name, xpath, type));
165     }
166 
167     public void addColumnWithXPathName(String columnNameXPathExpression,
168             String expression, int type) {
169         XPath columnNameXPath = createColumnXPath(columnNameXPathExpression);
170         XPath xpath = createColumnXPath(expression);
171         addColumn(new XMLTableColumnDefinition(columnNameXPath, xpath, type));
172     }
173 
174     public void addStringColumn(String name, String expression) {
175         addColumn(name, expression, XMLTableColumnDefinition.STRING_TYPE);
176     }
177 
178     public void addNumberColumn(String name, String expression) {
179         addColumn(name, expression, XMLTableColumnDefinition.NUMBER_TYPE);
180     }
181 
182     public void addColumn(XMLTableColumnDefinition column) {
183         clearCaches();
184         columns.add(column);
185     }
186 
187     public void removeColumn(XMLTableColumnDefinition column) {
188         clearCaches();
189         columns.remove(column);
190     }
191 
192     public void clear() {
193         clearCaches();
194         columns.clear();
195     }
196 
197     public XMLTableColumnDefinition getColumn(int index) {
198         if (columnArray == null) {
199             columnArray = new XMLTableColumnDefinition[columns.size()];
200             columns.toArray(columnArray);
201         }
202 
203         return columnArray[index];
204     }
205 
206     public XMLTableColumnDefinition getColumn(String columnName) {
207         if (columnNameIndex == null) {
208             columnNameIndex = new HashMap();
209 
210             for (Iterator it = columns.iterator(); it.hasNext();) {
211                 XMLTableColumnDefinition column = (XMLTableColumnDefinition) it
212                         .next();
213                 columnNameIndex.put(column.getName(), column);
214             }
215         }
216 
217         return (XMLTableColumnDefinition) columnNameIndex.get(columnName);
218     }
219 
220     /***
221      * Getter for property rowXPath.
222      * 
223      * @return Value of property rowXPath.
224      */
225     public XPath getRowXPath() {
226         return rowXPath;
227     }
228 
229     /***
230      * Setter for property rowXPath.
231      * 
232      * @param rowXPath
233      *            New value of property rowXPath.
234      */
235     public void setRowXPath(XPath rowXPath) {
236         this.rowXPath = rowXPath;
237     }
238 
239     public void setRowExpression(String xpath) {
240         setRowXPath(createXPath(xpath));
241     }
242 
243     
244     
245     public Object getVariableValue(String namespaceURI, String prefix,
246             String localName) {
247         XMLTableColumnDefinition column = getColumn(localName);
248 
249         if (column != null) {
250             return column.getValue(rowValue);
251         }
252 
253         return null;
254     }
255 
256     
257     
258     protected XPath createXPath(String expression) {
259         return DocumentHelper.createXPath(expression);
260     }
261 
262     protected XPath createColumnXPath(String expression) {
263         XPath xpath = createXPath(expression);
264 
265         
266         xpath.setVariableContext(this);
267 
268         return xpath;
269     }
270 
271     protected void clearCaches() {
272         columnArray = null;
273         columnNameIndex = null;
274     }
275 
276     protected void handleException(Exception e) {
277         
278         System.out.println("Caught: " + e);
279     }
280 }
281 
282 
283 
284 
285 
286 
287 
288 
289 
290 
291 
292 
293 
294 
295 
296 
297 
298 
299 
300 
301 
302 
303 
304 
305 
306 
307 
308 
309 
310 
311 
312 
313 
314 
315 
316 
317