001/*
002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
003 * 
004 * This software is open source. 
005 * See the bottom of this file for the licence.
006 * 
007 * $Id: XMLTableDefinition.java,v 1.1 2001/12/14 11:32:09 jstrachan Exp $
008 */
009
010package org.dom4j.swing;
011
012import java.io.Serializable;
013import java.util.ArrayList;
014import java.util.HashMap;
015import java.util.Iterator;
016import java.util.List;
017import java.util.Map;
018   
019import org.dom4j.Document;
020import org.dom4j.DocumentHelper;
021import org.dom4j.Element;
022import org.dom4j.XPath;
023import org.jaxen.VariableContext;
024
025/** <p><code>XMLTableDefinition</code> represents a
026  * table definition based on XPath expression evaluated
027  * on an XML document.</p>
028  *
029  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
030  * @version $Revision: 1.1 $ 
031  */
032public class XMLTableDefinition implements Serializable, VariableContext {
033
034    /** Holds value of property rowXPath. */
035    private XPath rowXPath;
036    
037    /** The columns to display in this table */
038    private List columns = new ArrayList();
039    
040    /** integer index array cache */
041    private XMLTableColumnDefinition[] columnArray;
042    /** name index cache */
043    private Map columnNameIndex;
044    
045    /** for cross-row variables */
046    private VariableContext variableContext;
047    
048    /** stores the current row value for the variableContext */
049    private Object rowValue;
050    
051    public XMLTableDefinition() {
052    }
053
054    /** Loads an XML table definition from an XML definition document */
055    public static XMLTableDefinition load(Document definition) {
056        return load( definition.getRootElement() );
057    }
058    
059    /** Loads an XML table definition from an XML definition document */
060    public static XMLTableDefinition load(Element definition) {
061        XMLTableDefinition answer = new XMLTableDefinition();
062        answer.setRowExpression( definition.attributeValue( "select" ) );
063        for (Iterator iter = definition.elementIterator( "column" ); iter.hasNext(); ) {
064            Element element = (Element) iter.next();
065            String expression = element.attributeValue( "select" );
066            String name = element.getText();
067            String typeName = element.attributeValue( "type", "string" );            
068            int type = XMLTableColumnDefinition.parseType( typeName );
069            answer.addColumn( name, expression, type );
070        }
071        return answer;
072    }
073    
074    
075    public Class getColumnClass(int columnIndex) {
076        return getColumn(columnIndex).getColumnClass();
077    }
078    
079    public int getColumnCount() {
080        return columns.size();
081    }
082    
083    public String getColumnName(int columnIndex) {
084        return getColumn(columnIndex).getName();
085    }
086     
087    public XPath getColumnXPath(int columnIndex) {
088        return getColumn(columnIndex).getXPath();
089    }
090     
091    public synchronized Object getValueAt(Object row, int columnIndex) {
092        XMLTableColumnDefinition column = getColumn(columnIndex);
093        Object answer = null;
094        synchronized (this) {
095            this.rowValue = row;
096            answer = column.getValue(row);
097            this.rowValue = null;
098        }
099        return answer;
100    }
101     
102
103    public void addColumn(String name, String expression) {
104        addColumn( name, expression, XMLTableColumnDefinition.OBJECT_TYPE );
105    }
106    
107    public void addColumn(String name, String expression, int type) {
108        XPath xpath = createColumnXPath( expression );
109        addColumn( new XMLTableColumnDefinition( name, xpath, type ) );
110    }
111    
112    public void addStringColumn(String name, String expression) {
113        addColumn( name, expression, XMLTableColumnDefinition.STRING_TYPE );
114    }
115    
116    public void addNumberColumn(String name, String expression) {
117        addColumn( name, expression, XMLTableColumnDefinition.NUMBER_TYPE );
118    }
119    
120    public void addColumn(XMLTableColumnDefinition column) {
121        clearCaches();
122        columns.add( column );
123    }
124    
125    public void removeColumn(XMLTableColumnDefinition column) {
126        clearCaches();
127        columns.remove( column );
128    }
129    
130    public void clear() {
131        clearCaches();
132        columns.clear();
133    }
134    
135    public XMLTableColumnDefinition getColumn(int index) {
136        if ( columnArray == null ) {
137            columnArray = new XMLTableColumnDefinition[ columns.size() ];
138            columns.toArray( columnArray );
139        }
140        return columnArray[index];
141    }
142    
143    public XMLTableColumnDefinition getColumn(String columnName) {
144        if ( columnNameIndex == null ) {
145            columnNameIndex = new HashMap();
146            for (Iterator iter = columns.iterator(); iter.hasNext(); ) {
147                XMLTableColumnDefinition column = (XMLTableColumnDefinition) iter.next();
148                columnNameIndex.put( column.getName(), column );
149            }
150        }
151        return (XMLTableColumnDefinition) columnNameIndex.get(columnName);
152    }
153    
154    /** Getter for property rowXPath.
155     * @return Value of property rowXPath.
156     */
157    public XPath getRowXPath() {
158        return rowXPath;
159    }
160    
161    /** Setter for property rowXPath.
162     * @param rowXPath New value of property rowXPath.
163     */
164    public void setRowXPath(XPath rowXPath) {
165        this.rowXPath = rowXPath;
166    }
167    
168    public void setRowExpression(String xpath) {
169        setRowXPath( createXPath( xpath ) );
170    }
171    
172    
173    // VariableContext interface
174    //-------------------------------------------------------------------------                
175    public Object getVariableValue(
176        String namespaceURI,
177        String prefix,
178        String localName
179    ) {
180        XMLTableColumnDefinition column = getColumn(localName);
181        if ( column != null ) {
182            return column.getValue( rowValue );
183        }
184        return null;
185    }
186    
187    // Implementation methods
188    //-------------------------------------------------------------------------                
189    protected XPath createXPath(String expression) {
190        return DocumentHelper.createXPath(expression);
191    }
192    
193    protected XPath createColumnXPath(String expression) {
194        XPath xpath = createXPath( expression );
195        // associate my variable context
196        xpath.setVariableContext( this );
197        return xpath;
198    }
199
200    
201    protected void clearCaches() {
202        columnArray = null;
203        columnNameIndex = null;
204    }
205    
206    protected void handleException(Exception e) {
207        // #### should use jakarta commons-logging
208        System.out.println( "Caught: " + e );
209    }
210}
211
212
213
214
215/*
216 * Redistribution and use of this software and associated documentation
217 * ("Software"), with or without modification, are permitted provided
218 * that the following conditions are met:
219 *
220 * 1. Redistributions of source code must retain copyright
221 *    statements and notices.  Redistributions must also contain a
222 *    copy of this document.
223 *
224 * 2. Redistributions in binary form must reproduce the
225 *    above copyright notice, this list of conditions and the
226 *    following disclaimer in the documentation and/or other
227 *    materials provided with the distribution.
228 *
229 * 3. The name "DOM4J" must not be used to endorse or promote
230 *    products derived from this Software without prior written
231 *    permission of MetaStuff, Ltd.  For written permission,
232 *    please contact dom4j-info@metastuff.com.
233 *
234 * 4. Products derived from this Software may not be called "DOM4J"
235 *    nor may "DOM4J" appear in their names without prior written
236 *    permission of MetaStuff, Ltd. DOM4J is a registered
237 *    trademark of MetaStuff, Ltd.
238 *
239 * 5. Due credit should be given to the DOM4J Project
240 *    (http://dom4j.org/).
241 *
242 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
243 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
244 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
245 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
246 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
247 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
248 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
249 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
250 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
251 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
252 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
253 * OF THE POSSIBILITY OF SUCH DAMAGE.
254 *
255 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
256 *
257 * $Id: XMLTableDefinition.java,v 1.1 2001/12/14 11:32:09 jstrachan Exp $
258 */