Clover coverage report -
Coverage timestamp: Sun Nov 16 2008 23:05:30 GMT
file stats: LOC: 741   Methods: 35
NCLOC: 458   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
MetaData.java 46.4% 65.1% 71.4% 59.5%
coverage coverage
 1    /*
 2    * Licensed to the Apache Software Foundation (ASF) under one or more
 3    * contributor license agreements. See the NOTICE file distributed with
 4    * this work for additional information regarding copyright ownership.
 5    * The ASF licenses this file to You under the Apache License, Version 2.0
 6    * (the "License"); you may not use this file except in compliance with
 7    * the License. You may obtain a copy of the License at
 8    *
 9    * http://www.apache.org/licenses/LICENSE-2.0
 10    *
 11    * Unless required by applicable law or agreed to in writing, software
 12    * distributed under the License is distributed on an "AS IS" BASIS,
 13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14    * See the License for the specific language governing permissions and
 15    * limitations under the License.
 16    *
 17    * $Id: MetaData.java 713233 2008-11-12 01:01:36Z vgritsenko $
 18    */
 19   
 20    package org.apache.xindice.core.meta;
 21   
 22    import org.apache.commons.logging.Log;
 23    import org.apache.commons.logging.LogFactory;
 24    import org.apache.xindice.xml.TextWriter;
 25    import org.apache.xindice.xml.XMLSerializable;
 26    import org.apache.xindice.xml.dom.DocumentImpl;
 27   
 28    import org.w3c.dom.DOMException;
 29    import org.w3c.dom.Document;
 30    import org.w3c.dom.Element;
 31    import org.w3c.dom.Node;
 32    import org.w3c.dom.NodeList;
 33   
 34    import java.util.Date;
 35    import java.util.Enumeration;
 36    import java.util.Hashtable;
 37    import java.util.Vector;
 38   
 39    /**
 40    * Implements the MetaData interface.
 41    *
 42    * <pre>
 43    * &lt;meta&gt;
 44    * &lt;system [type="doc|col"] [href="uri"]/&gt;
 45    * &lt;attrs&gt;
 46    * &lt;attr name="name" value="value"/&gt;
 47    * &lt;attr name="name" value="value"/&gt;
 48    * &lt;/attrs&gt;
 49    * &lt;custom&gt;
 50    * ...
 51    * &lt;/custom&gt;
 52    * &lt;/meta&gt;
 53    * </pre>
 54    *
 55    * @author ku
 56    * @author Dave Viner &lt;dviner@apache.org&gt;
 57    * @version $Revision: 713233 $, $Date: 2008-11-12 01:01:36 +0000 (Wed, 12 Nov 2008) $
 58    */
 59    public class MetaData implements XMLSerializable {
 60   
 61    private static final Log log = LogFactory.getLog(MetaData.class);
 62   
 63    public static final short UNKNOWN = 0;
 64    public static final short COLLECTION = 1;
 65    public static final short DOCUMENT = 2;
 66    public static final short LINK = 3;
 67   
 68    public static final String NS_URI = "http://apache.org/xindice/metadata";
 69    public static final boolean USE_NS = true;
 70   
 71    private static final String E_META = "meta";
 72    private static final String E_SYSTEM = "system";
 73    private static final String E_ATTRS = "attrs";
 74    private static final String E_ATTR = "attr";
 75    private static final String E_CUSTOM = "custom";
 76    private static final String E_CREATED = "created";
 77    private static final String E_MODIFIED = "modified";
 78   
 79    private static final String A_NAME = "name";
 80    private static final String A_VALUE = "value";
 81    private static final String A_TYPE = "type";
 82    private static final String A_HREF = "href";
 83   
 84    private static final Enumeration EMPTY = new Vector().elements();
 85   
 86    private transient boolean dirty;
 87    private transient long created;
 88    private transient long modified;
 89    private transient String owner;
 90   
 91    private short type = UNKNOWN;
 92    private String link;
 93    private Hashtable attrs;
 94    private Document custom;
 95   
 96   
 97  3851 public MetaData() {
 98    }
 99   
 100    /**
 101    * @param owner the owner of this metadata.
 102    */
 103  18 public MetaData(String owner) {
 104  18 this.owner = owner;
 105    }
 106   
 107   
 108    /**
 109    * @param type the type of object for this metadata
 110    * @param owner the owner of this metadata
 111    * @param created the time when this was created
 112    * @param modified the time when this was modified.
 113    */
 114  7592 public MetaData(short type, String owner, long created, long modified) {
 115  7592 this.type = type;
 116  7592 this.owner = owner;
 117  7592 this.created = created;
 118  7592 this.modified = modified;
 119    }
 120   
 121    /**
 122    * @param elem an XML representation of the desired metadata.
 123    */
 124  0 public MetaData(Element elem) {
 125  0 streamFromXML(elem);
 126    }
 127   
 128    /**
 129    * Returns whether this MetaData is dirty
 130    *
 131    * @return boolean
 132    */
 133  0 public final boolean isDirty() {
 134  0 return dirty;
 135    }
 136   
 137    /**
 138    * Reset the dirtiness of this object
 139    *
 140    * @param dirty
 141    */
 142  7630 public final void setDirty(boolean dirty) {
 143  7630 this.dirty = dirty;
 144    }
 145   
 146    /**
 147    * Returns the time of creation
 148    * @return long creation time
 149    */
 150  32 public long getCreatedTime() {
 151  32 return created;
 152    }
 153   
 154    /**
 155    * Returns the time of last modification
 156    * @return long last modified time
 157    */
 158  32 public long getLastModifiedTime() {
 159  32 return modified;
 160    }
 161   
 162    /**
 163    * Returns the type of the owner object, e.g., COLLECTION,
 164    * DOCUMENT, or LINK
 165    * @return short the object type
 166    */
 167  3864 public short getType() {
 168  3864 return type;
 169    }
 170   
 171    /**
 172    * Returns the canonical name of the owner object.
 173    * @return String the canonical name of the owner object
 174    */
 175  0 public String getOwner() {
 176  0 return owner;
 177    }
 178   
 179    /**
 180    * Returns enumeration of all attributes
 181    * @return Enumeration of attributes
 182    */
 183  12 public Enumeration getAttributeKeys() {
 184  12 if (attrs == null) {
 185  6 return EMPTY;
 186    }
 187   
 188  6 return attrs.keys();
 189    }
 190   
 191    /**
 192    * Retrieves the attribute by name
 193    * @param name the attribute name
 194    * @return String the value of attribute, or null if not found
 195    */
 196  14 public Object getAttribute(final Object name) {
 197  14 if (attrs == null) {
 198  0 return null;
 199    }
 200   
 201  14 return attrs.get(name);
 202    }
 203   
 204  0 public Boolean getAttributeAsBoolean(final Object name) {
 205  0 Object o = getAttribute(name);
 206  0 if (o == null) {
 207  0 return null;
 208    }
 209   
 210  0 if (o instanceof Boolean) {
 211  0 return (Boolean) o;
 212    }
 213   
 214  0 if (o instanceof Number) {
 215  0 Number n = (Number) o;
 216  0 return n.intValue() != 0 ? Boolean.TRUE : Boolean.FALSE;
 217    }
 218   
 219  0 return Boolean.valueOf(o.toString());
 220    }
 221   
 222  0 public Integer getAttributeAsInteger(final Object name) {
 223  0 Object o = getAttribute(name);
 224  0 if (o == null) {
 225  0 return null;
 226    }
 227   
 228  0 if (o instanceof Integer) {
 229  0 return (Integer) o;
 230    }
 231   
 232  0 if (o instanceof Number) {
 233  0 Number n = (Number) o;
 234  0 return new Integer(n.intValue());
 235    }
 236   
 237  0 try {
 238  0 return new Integer(o.toString());
 239    } catch (Exception e) {
 240  0 return null;
 241    }
 242    }
 243   
 244  0 public Long getAttributeAsLong(final Object name) {
 245  0 Object o = getAttribute(name);
 246  0 if (o == null) {
 247  0 return null;
 248    }
 249   
 250  0 if (o instanceof Long) {
 251  0 return (Long) o;
 252    }
 253   
 254  0 if (o instanceof Number) {
 255  0 Number n = (Number) o;
 256  0 return new Long(n.longValue());
 257    }
 258   
 259  0 try {
 260  0 return new Long(o.toString());
 261    } catch (Exception e) {
 262  0 return null;
 263    }
 264    }
 265   
 266  0 public Short getAttributeAsShort(final Object name) {
 267  0 Object o = getAttribute(name);
 268  0 if (o == null) {
 269  0 return null;
 270    }
 271   
 272  0 if (o instanceof Short) {
 273  0 return (Short) o;
 274    }
 275   
 276  0 if (o instanceof Number) {
 277  0 Number n = (Number) o;
 278  0 return new Short(n.shortValue());
 279    }
 280   
 281  0 try {
 282  0 return new Short(o.toString());
 283    } catch (Exception e) {
 284  0 return null;
 285    }
 286    }
 287   
 288    /**
 289    * Sets the attribute by name
 290    * @param name the attribute name
 291    * @param value the attribute value
 292    * @return Object the old value, if any
 293    */
 294  7 public Object setAttribute(final Object name, final Object value) {
 295  7 if (attrs == null) {
 296  7 attrs = new Hashtable();
 297  7 dirty = true;
 298    }
 299   
 300  7 Object prev = attrs.put(name, value);
 301  7 if (prev == null || !prev.equals(value)) {
 302  7 dirty = true;
 303    }
 304   
 305  7 return prev;
 306    }
 307   
 308    /**
 309    * Remove an attribute by name
 310    * @param name the attribute to remove
 311    * @return Object the removed value
 312    */
 313  0 public Object removeAttribute(final Object name) {
 314  0 if (attrs == null) {
 315  0 return null;
 316    }
 317   
 318  0 Object prev = attrs.remove(name);
 319  0 if (prev != null) {
 320  0 dirty = true;
 321    }
 322   
 323  0 return prev;
 324    }
 325   
 326    /**
 327    * Returns the (optional) custom meta document
 328    * @return Document the custom meta document
 329    */
 330  16 public Document getCustomDocument() {
 331  16 return custom;
 332    }
 333   
 334    /**
 335    * Sets the (optional) custom meta document
 336    * @param doc the Document
 337    */
 338  3 public void setCustomDocument(Document doc) {
 339  3 this.custom = doc;
 340  3 this.dirty = true;
 341    }
 342   
 343    /**
 344    * Copies from another meta data
 345    * @param meta the meta to copy from
 346    */
 347  0 public void copyFrom(final MetaData meta) {
 348  0 this.created = meta.getCreatedTime();
 349  0 this.modified = meta.getLastModifiedTime();
 350  0 this.owner = meta.getOwner();
 351  0 this.type = meta.getType();
 352  0 copyDataFrom(meta);
 353    }
 354   
 355    /**
 356    * Copies only user data (link, attributes, custom document) from another meta data
 357    * @param meta the meta to copy from
 358    */
 359  12 public void copyDataFrom(final MetaData meta) {
 360  12 this.link = meta.getLinkTargetURI();
 361  12 this.attrs = null;
 362  12 for (Enumeration e = meta.getAttributeKeys(); e.hasMoreElements();) {
 363  6 Object key = e.nextElement();
 364  6 Object value = meta.getAttribute(key);
 365  6 if (this.attrs == null) {
 366  6 this.attrs = new Hashtable();
 367    }
 368  6 this.attrs.put(key, value);
 369    }
 370   
 371  12 this.custom = null;
 372  12 Document doc = meta.getCustomDocument();
 373  12 if (doc != null) {
 374  2 this.custom = new DocumentImpl();
 375  2 this.custom.appendChild(
 376    this.custom.importNode(doc.getDocumentElement(), true));
 377    }
 378   
 379  12 this.dirty = false;
 380    }
 381   
 382    /**
 383    * Returns the linked target URI, if this is a link
 384    * @return String the URI of the linked target
 385    */
 386  12 public String getLinkTargetURI() {
 387  12 return link;
 388    }
 389   
 390    //
 391    // Serialization to/from XML
 392    //
 393   
 394    /**
 395    * Stream this MetaData into an xml document
 396    * @param doc the xml document to be populated.
 397    */
 398  3786 public final Element streamToXML(Document doc) throws DOMException {
 399  3786 return streamToXML(doc, true);
 400    }
 401   
 402    /**
 403    * Stream this MetaData into an xml document
 404    * @param doc the xml document to populate
 405    * @param includeTime whether or not to include the create/modified times
 406    * @return Element the root element
 407    */
 408  3817 public final Element streamToXML(Document doc, boolean includeTime)
 409    throws DOMException {
 410   
 411  3817 Element root;
 412  3817 if (!USE_NS) {
 413  0 root = doc.createElement(E_META);
 414    } else {
 415  3817 root = doc.createElementNS(NS_URI, E_META);
 416  3817 root.setAttribute("xmlns", NS_URI);
 417    }
 418   
 419  3817 Element systemElement;
 420  3817 if (!USE_NS) {
 421  0 systemElement = doc.createElement(E_SYSTEM);
 422    } else {
 423  3817 systemElement = doc.createElementNS(NS_URI, E_SYSTEM);
 424    }
 425  3817 systemElement.setAttribute(A_TYPE, getTypeString(type));
 426  3817 root.appendChild(systemElement);
 427  3817 if (includeTime) {
 428  3817 Element timeElement;
 429  3817 if (!USE_NS) {
 430  0 timeElement = doc.createElement(E_ATTR);
 431    } else {
 432  3817 timeElement = doc.createElementNS(NS_URI, E_ATTR);
 433    }
 434  3817 timeElement.setAttribute(A_NAME, E_CREATED);
 435  3817 timeElement.setAttribute(A_VALUE, Long.toString(created));
 436  3817 systemElement.appendChild(timeElement);
 437   
 438  3817 if (!USE_NS) {
 439  0 timeElement = doc.createElement(E_ATTR);
 440    } else {
 441  3817 timeElement = doc.createElementNS(NS_URI, E_ATTR);
 442    }
 443  3817 timeElement.setAttribute(A_NAME, E_MODIFIED);
 444  3817 timeElement.setAttribute(A_VALUE, Long.toString(modified));
 445  3817 systemElement.appendChild(timeElement);
 446    }
 447  3817 if (link != null) {
 448  0 systemElement.setAttribute(A_HREF, link);
 449    }
 450   
 451  3817 if (attrs != null && attrs.size() > 0) {
 452  17 Element attrsElement;
 453  17 if (!USE_NS) {
 454  0 attrsElement = doc.createElement(E_ATTRS);
 455    } else {
 456  17 attrsElement = doc.createElementNS(NS_URI, E_ATTRS);
 457    }
 458  17 root.appendChild(attrsElement);
 459   
 460  17 for (Enumeration e = attrs.keys(); e.hasMoreElements();) {
 461  17 Object key = e.nextElement();
 462  17 Object value = attrs.get(key);
 463  17 if (key == null) {
 464  0 continue;
 465    }
 466   
 467  17 Element attrElement;
 468  17 if (!USE_NS) {
 469  0 attrElement = doc.createElement(E_ATTR);
 470    } else {
 471  17 attrElement = doc.createElementNS(NS_URI, E_ATTR);
 472    }
 473  17 attrsElement.appendChild(attrElement);
 474   
 475  17