View Javadoc

    1   /*
    2    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
    3    *
    4    * This software is open source.
    5    * See the bottom of this file for the licence.
    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     // VariableContext interface
    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     // Implementation methods
    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         // associate my variable context
    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         // #### should use jakarta commons-logging
    278         System.out.println("Caught: " + e);
    279     }
    280 }
    281
    282 /*
    283  * Redistribution and use of this software and associated documentation
    284  * ("Software"), with or without modification, are permitted provided that the
    285  * following conditions are met:
    286  *
    287  * 1. Redistributions of source code must retain copyright statements and
    288  * notices. Redistributions must also contain a copy of this document.
    289  *
    290  * 2. Redistributions in binary form must reproduce the above copyright notice,
    291  * this list of conditions and the following disclaimer in the documentation
    292  * and/or other materials provided with the distribution.
    293  *
    294  * 3. The name "DOM4J" must not be used to endorse or promote products derived
    295  * from this Software without prior written permission of MetaStuff, Ltd. For
    296  * written permission, please contact dom4j-info@metastuff.com.
    297  *
    298  * 4. Products derived from this Software may not be called "DOM4J" nor may
    299  * "DOM4J" appear in their names without prior written permission of MetaStuff,
    300  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
    301  *
    302  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
    303  *
    304  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
    305  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    306  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    307  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
    308  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    309  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    310  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    311  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    312  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    313  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    314  * POSSIBILITY OF SUCH DAMAGE.
    315  *
    316  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
    317  */