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