Coverage Report - org.codehaus.plexus.metadata.merge.Driver
 
Classes in this File Line Coverage Branch Coverage Complexity
Driver
0 %
0/189
0 %
0/81
3,121
 
 1  
 /* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  //------100-columns-wide------>|*/
 2  
 // for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
 3  
 
 4  
 package org.codehaus.plexus.metadata.merge;
 5  
 
 6  
 import java.io.InputStream;
 7  
 import java.io.IOException;
 8  
 import java.io.Reader;
 9  
 
 10  
 // not J2ME classes -- remove if you want to run in MIDP devices
 11  
 import java.net.URL;
 12  
 import java.net.MalformedURLException;
 13  
 
 14  
 
 15  
 // not J2ME classes
 16  
 import java.io.FileInputStream;
 17  
 import java.io.FileNotFoundException;
 18  
 
 19  
 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
 20  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 21  
 import org.xml.sax.Attributes;
 22  
 import org.xml.sax.DTDHandler;
 23  
 import org.xml.sax.ContentHandler;
 24  
 import org.xml.sax.EntityResolver;
 25  
 import org.xml.sax.ErrorHandler;
 26  
 import org.xml.sax.InputSource;
 27  
 import org.xml.sax.Locator;
 28  
 import org.xml.sax.SAXException;
 29  
 import org.xml.sax.SAXParseException;
 30  
 import org.xml.sax.SAXNotRecognizedException;
 31  
 import org.xml.sax.SAXNotSupportedException;
 32  
 import org.xml.sax.XMLReader;
 33  
 import org.xml.sax.helpers.DefaultHandler;
 34  
 
 35  
 /**
 36  
  * SAX2 Driver that pulls events from XmlPullParser
 37  
  * and comverts them into SAX2 callbacks.
 38  
  *
 39  
  * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
 40  
  */
 41  
 
 42  
 public class Driver implements Locator, XMLReader, Attributes
 43  
 {
 44  
 
 45  
     protected static final String DECLARATION_HANDLER_PROPERTY =
 46  
         "http://xml.org/sax/properties/declaration-handler";
 47  
 
 48  
     protected static final String LEXICAL_HANDLER_PROPERTY =
 49  
         "http://xml.org/sax/properties/lexical-handler";
 50  
 
 51  
     protected static final String NAMESPACES_FEATURE =
 52  
         "http://xml.org/sax/features/namespaces";
 53  
 
 54  
     protected static final String NAMESPACE_PREFIXES_FEATURE =
 55  
         "http://xml.org/sax/features/namespace-prefixes";
 56  
 
 57  
     protected static final String VALIDATION_FEATURE =
 58  
         "http://xml.org/sax/features/validation";
 59  
 
 60  
     protected static final String APACHE_SCHEMA_VALIDATION_FEATURE =
 61  
         "http://apache.org/xml/features/validation/schema";
 62  
 
 63  
     protected static final String APACHE_DYNAMIC_VALIDATION_FEATURE =
 64  
         "http://apache.org/xml/features/validation/dynamic";
 65  
 
 66  0
     protected ContentHandler contentHandler = new DefaultHandler();
 67  0
     protected ErrorHandler errorHandler = new DefaultHandler();;
 68  
 
 69  
     protected String systemId;
 70  
 
 71  
     protected XmlPullParser pp;
 72  
 
 73  
     public Driver() throws XmlPullParserException
 74  0
     {
 75  0
         pp = new MXParser();
 76  
         
 77  
         try
 78  
         {
 79  0
             setFeature( NAMESPACES_FEATURE, true );
 80  0
             setFeature( NAMESPACE_PREFIXES_FEATURE, true );
 81  
             
 82  
         }
 83  0
         catch ( Exception e )
 84  
         {
 85  0
             e.printStackTrace();
 86  0
         }
 87  0
     }
 88  
     
 89  
     // -- Attributes interface
 90  
 
 91  0
     public int getLength() { return pp.getAttributeCount(); }
 92  0
     public String getURI(int index) { return pp.getAttributeNamespace(index); }
 93  0
     public String getLocalName(int index) { return pp.getAttributeName(index); }
 94  
     public String getQName(int index) {
 95  0
         final String prefix = pp.getAttributePrefix(index);
 96  0
         if(prefix != null) {
 97  0
             return prefix+':'+pp.getAttributeName(index);
 98  
         } else {
 99  0
             return pp.getAttributeName(index);
 100  
         }
 101  
     }
 102  0
     public String getType(int index) { return pp.getAttributeType(index); }
 103  0
     public String getValue(int index) { return pp.getAttributeValue(index); }
 104  
 
 105  
     public int getIndex(String uri, String localName) {
 106  0
         for (int i = 0; i < pp.getAttributeCount(); i++)
 107  
         {
 108  0
             if(pp.getAttributeNamespace(i).equals(uri)
 109  
                && pp.getAttributeName(i).equals(localName))
 110  
             {
 111  0
                 return i;
 112  
             }
 113  
 
 114  
         }
 115  0
         return -1;
 116  
     }
 117  
 
 118  
     public int getIndex(String qName) {
 119  0
         for (int i = 0; i < pp.getAttributeCount(); i++)
 120  
         {
 121  0
             if(pp.getAttributeName(i).equals(qName))
 122  
             {
 123  0
                 return i;
 124  
             }
 125  
 
 126  
         }
 127  0
         return -1;
 128  
     }
 129  
 
 130  
     public String getType(String uri, String localName) {
 131  0
         for (int i = 0; i < pp.getAttributeCount(); i++)
 132  
         {
 133  0
             if(pp.getAttributeNamespace(i).equals(uri)
 134  
                && pp.getAttributeName(i).equals(localName))
 135  
             {
 136  0
                 return pp.getAttributeType(i);
 137  
             }
 138  
 
 139  
         }
 140  0
         return null;
 141  
     }
 142  
     public String getType(String qName) {
 143  0
         for (int i = 0; i < pp.getAttributeCount(); i++)
 144  
         {
 145  0
             if(pp.getAttributeName(i).equals(qName))
 146  
             {
 147  0
                 return pp.getAttributeType(i);
 148  
             }
 149  
 
 150  
         }
 151  0
         return null;
 152  
     }
 153  
     public String getValue(String uri, String localName) {
 154  0
         return pp.getAttributeValue(uri, localName);
 155  
     }
 156  
     public String getValue(String qName) {
 157  0
         return pp.getAttributeValue(null, qName);
 158  
     }
 159  
 
 160  
     // -- Locator interface
 161  
 
 162  0
     public String getPublicId() { return null; }
 163  0
     public String getSystemId() { return systemId; }
 164  0
     public int getLineNumber() { return pp.getLineNumber(); }
 165  0
     public int getColumnNumber() { return pp.getColumnNumber(); }
 166  
 
 167  
     // --- XMLReader interface
 168  
 
 169  
     //"http://xml.org/sax/features/namespaces",
 170  
     //true
 171  
     
 172  
     public boolean getFeature(String name)
 173  
         throws SAXNotRecognizedException, SAXNotSupportedException
 174  
     {
 175  0
         if(NAMESPACES_FEATURE.equals(name)) {
 176  0
             return pp.getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
 177  0
         } else if(NAMESPACE_PREFIXES_FEATURE.equals(name)) {
 178  0
             return pp.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES);
 179  0
         } else if(VALIDATION_FEATURE.equals(name)) {
 180  0
             return pp.getFeature(XmlPullParser.FEATURE_VALIDATION);
 181  
             //        } else if(APACHE_SCHEMA_VALIDATION_FEATURE.equals(name)) {
 182  
             //            return false;  //TODO
 183  
             //        } else if(APACHE_DYNAMIC_VALIDATION_FEATURE.equals(name)) {
 184  
             //            return false; //TODO
 185  
         } else {
 186  0
             return pp.getFeature(name);
 187  
             //throw new SAXNotRecognizedException("unrecognized feature "+name);
 188  
         }
 189  
     }
 190  
 
 191  
     public void setFeature (String name, boolean value)
 192  
         throws SAXNotRecognizedException, SAXNotSupportedException
 193  
     {
 194  
         try {
 195  0
             if(NAMESPACES_FEATURE.equals(name)) {
 196  0
                 pp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, value);
 197  0
             } else if(NAMESPACE_PREFIXES_FEATURE.equals(name)) {
 198  0
                 if(pp.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES) != value) {
 199  0
                     pp.setFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, value);
 200  
                 }
 201  0
             } else if(VALIDATION_FEATURE.equals(name)) {
 202  0
                 pp.setFeature(XmlPullParser.FEATURE_VALIDATION, value);
 203  
             } else {
 204  0
                 pp.setFeature(name, value);
 205  
                 //throw new SAXNotRecognizedException("unrecognized feature "+name);
 206  
             }
 207  0
         } catch(XmlPullParserException ex) {
 208  0
             throw new SAXNotSupportedException("problem with setting feature "+name+": "+ex);
 209  0
         }
 210  0
     }
 211  
 
 212  
     public Object getProperty (String name)
 213  
         throws SAXNotRecognizedException, SAXNotSupportedException
 214  
     {
 215  0
         if(DECLARATION_HANDLER_PROPERTY.equals(name)) {
 216  0
             return null;
 217  0
         } else if(LEXICAL_HANDLER_PROPERTY.equals(name)) {
 218  0
             return null;
 219  
         } else {
 220  0
             return pp.getProperty(name);
 221  
             //throw new SAXNotRecognizedException("not recognized get property "+name);
 222  
         }
 223  
     }
 224  
 
 225  
     public void setProperty (String name, Object value)
 226  
         throws SAXNotRecognizedException, SAXNotSupportedException
 227  
     {
 228  
         //
 229  0
         if(DECLARATION_HANDLER_PROPERTY.equals(name)) {
 230  0
             throw new SAXNotSupportedException("not supported setting property "+name);//+" to "+value);
 231  0
         } else if(LEXICAL_HANDLER_PROPERTY.equals(name)) {
 232  0
             throw new SAXNotSupportedException("not supported setting property "+name);//+" to "+value);
 233  
         } else {
 234  
             try {
 235  0
                 pp.setProperty(name, value);
 236  0
             } catch(XmlPullParserException ex) {
 237  0
                 throw new SAXNotSupportedException("not supported set property "+name+": "+ ex);
 238  0
             }
 239  
             //throw new SAXNotRecognizedException("not recognized set property "+name);
 240  
         }
 241  0
     }
 242  
 
 243  0
     public void setEntityResolver (EntityResolver resolver) {}
 244  
 
 245  0
     public EntityResolver getEntityResolver () { return null; }
 246  
 
 247  0
     public void setDTDHandler (DTDHandler handler) {}
 248  
 
 249  0
     public DTDHandler getDTDHandler () { return null; }
 250  
 
 251  
     public void setContentHandler (ContentHandler handler)
 252  
     {
 253  0
         this.contentHandler = handler;
 254  0
     }
 255  
 
 256  0
     public ContentHandler getContentHandler() { return contentHandler; }
 257  
 
 258  
     public void setErrorHandler(ErrorHandler handler) {
 259  0
         this.errorHandler = handler;
 260  0
     }
 261  
 
 262  0
     public ErrorHandler getErrorHandler() { return errorHandler; }
 263  
 
 264  
     public void parse(InputSource source) throws SAXException, IOException
 265  
     {
 266  
 
 267  0
         systemId = source.getSystemId();
 268  0
         contentHandler.setDocumentLocator(this);
 269  
 
 270  0
         final Reader reader = source.getCharacterStream();
 271  
         try {
 272  0
             if (reader == null) {
 273  0
                 InputStream stream = source.getByteStream();
 274  0
                 final String encoding = source.getEncoding();
 275  
 
 276  0
                 if (stream == null) {
 277  0
                     systemId = source.getSystemId();
 278  0
                     if(systemId == null) {
 279  0
                         SAXParseException saxException = new SAXParseException(
 280  
                             "null source systemId" , this);
 281  0
                         errorHandler.fatalError(saxException);
 282  0
                         return;
 283  
                     }
 284  
                     // NOTE: replace with Connection to run in J2ME environment
 285  
                     try {
 286  0
                         final URL url = new URL(systemId);
 287  0
                         stream = url.openStream();
 288  0
                     } catch (MalformedURLException nue) {
 289  
                         try {
 290  0
                             stream = new FileInputStream(systemId);
 291  0
                         } catch (FileNotFoundException fnfe) {
 292  0
                             final SAXParseException saxException = new SAXParseException(
 293  
                                 "could not open file with systemId "+systemId, this, fnfe);
 294  0
                             errorHandler.fatalError(saxException);
 295  0
                             return;
 296  0
                         }
 297  0
                     }
 298  
                 }
 299  0
                 pp.setInput(stream, encoding);
 300  0
             } else {
 301  0
                 pp.setInput(reader);
 302  
             }
 303  0
         } catch (XmlPullParserException ex)  {
 304  0
             final SAXParseException saxException = new SAXParseException(
 305  
                 "parsing initialization error: "+ex, this, ex);
 306  
             //if(DEBUG) ex.printStackTrace();
 307  0
             errorHandler.fatalError(saxException);
 308  0
             return;
 309  0
         }
 310  
 
 311  
         // start parsing - move to first start tag
 312  
         try {
 313  0
             contentHandler.startDocument();
 314  
             // get first event
 315  0
             pp.next();
 316  
             // it should be start tag...
 317  0
             if(pp.getEventType() != XmlPullParser.START_TAG) {
 318  0
                 final SAXParseException saxException = new SAXParseException(
 319  
                     "expected start tag not"+pp.getPositionDescription(), this);
 320  
                 //throw saxException;
 321  0
                 errorHandler.fatalError(saxException);
 322  0
                 return;
 323  
             }
 324  0
         } catch (XmlPullParserException ex)  {
 325  0
             final SAXParseException saxException = new SAXParseException(
 326  
                 "parsing initialization error: "+ex, this, ex);
 327  
             //ex.printStackTrace();
 328  0
             errorHandler.fatalError(saxException);
 329  0
             return;
 330  0
         }
 331  
 
 332  
         // now real parsing can start!
 333  
 
 334  0
         parseSubTree(pp);
 335  
 
 336  
         // and finished ...
 337  
 
 338  0
         contentHandler.endDocument();
 339  0
     }
 340  
 
 341  
     public void parse(String systemId) throws SAXException, IOException {
 342  0
         parse(new InputSource(systemId));
 343  0
     }
 344  
 
 345  
 
 346  
     public void parseSubTree(XmlPullParser pp) throws SAXException, IOException {
 347  0
         this.pp = pp;
 348  0
         final boolean namespaceAware = pp.getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
 349  
         try {
 350  0
             if(pp.getEventType() != XmlPullParser.START_TAG) {
 351  0
                 throw new SAXException(
 352  
                     "start tag must be read before skiping subtree"+pp.getPositionDescription());
 353  
             }
 354  0
             final int[] holderForStartAndLength = new int[2];
 355  0
             final StringBuilder rawName = new StringBuilder(16);
 356  0
             String prefix = null;
 357  0
             String name = null;
 358  0
             int level = pp.getDepth() - 1;
 359  0
             int type = XmlPullParser.START_TAG;
 360  
 
 361  
             LOOP:
 362  
             do {
 363  0
                 switch(type) {
 364  
                     case XmlPullParser.START_TAG:
 365  0
                         if(namespaceAware) {
 366  0
                             final int depth = pp.getDepth() - 1;
 367  0
                             final int countPrev =
 368  
                                 (level > depth) ? pp.getNamespaceCount(depth) : 0;
 369  
                             //int countPrev = pp.getNamespaceCount(pp.getDepth() - 1);
 370  0
                             final int count = pp.getNamespaceCount(depth + 1);
 371  0
                             for (int i = countPrev; i < count; i++)
 372  
                             {
 373  0
                                 contentHandler.startPrefixMapping(
 374  
                                     pp.getNamespacePrefix(i),
 375  
                                     pp.getNamespaceUri(i)
 376  
                                 );
 377  
                             }
 378  0
                             name = pp.getName();
 379  0
                             prefix = pp.getPrefix();
 380  0
                             if(prefix != null) {
 381  0
                                 rawName.setLength(0);
 382  0
                                 rawName.append(prefix);
 383  0
                                 rawName.append(':');
 384  0
                                 rawName.append(name);
 385  
                             }
 386  0
                             startElement(pp.getNamespace(),
 387  
                                          name,
 388  
                                          prefix != null ? name : rawName.toString());
 389  0
                         } else {
 390  0
                             startElement(pp.getNamespace(),
 391  
                                          pp.getName(),
 392  
                                          pp.getName());
 393  
                         }
 394  
                         //++level;
 395  
 
 396  0
                         break;
 397  
                     case XmlPullParser.TEXT:
 398  0
                         final char[] chars = pp.getTextCharacters(holderForStartAndLength);
 399  0
                         contentHandler.characters(chars,
 400  
                                                   holderForStartAndLength[0], //start
 401  
                                                   holderForStartAndLength[1] //len
 402  
                                                  );
 403  0
                         break;
 404  
                     case XmlPullParser.END_TAG:
 405  
                         //--level;
 406  0
                         if(namespaceAware) {
 407  0
                             name = pp.getName();
 408  0
                             prefix = pp.getPrefix();
 409  0
                             if(prefix != null) {
 410  0
                                 rawName.setLength(0);
 411  0
                                 rawName.append(prefix);
 412  0
                                 rawName.append(':');
 413  0
                                 rawName.append(name);
 414  
                             }
 415  0
                             contentHandler.endElement(pp.getNamespace(),
 416  
                                                       name,
 417  
                                                       prefix != null ? name : rawName.toString()
 418  
                                                      );
 419  
                             // when entering show prefixes for all levels!!!!
 420  0
                             final int depth = pp.getDepth();
 421  0
                             final int countPrev =
 422  
                                 (level > depth) ? pp.getNamespaceCount(pp.getDepth()) : 0;
 423  0
                             int count = pp.getNamespaceCount(pp.getDepth() - 1);
 424  
                             // undeclare them in reverse order
 425  0
                             for (int i = count - 1; i >= countPrev; i--)
 426  
                             {
 427  0
                                 contentHandler.endPrefixMapping(
 428  
                                     pp.getNamespacePrefix(i)
 429  
                                 );
 430  
                             }
 431  0
                         } else {
 432  0
                             contentHandler.endElement(pp.getNamespace(),
 433  
                                                       pp.getName(),
 434  
                                                       pp.getName()
 435  
                                                      );
 436  
 
 437  
                         }
 438  0
                         break;
 439  
                     case XmlPullParser.END_DOCUMENT:
 440  0
                         break LOOP;
 441  
                 }
 442  0
                 type = pp.next();
 443  0
             } while(pp.getDepth() > level);
 444  0
         } catch (XmlPullParserException ex)  {
 445  0
             final SAXParseException saxException = new SAXParseException("parsing error: "+ex, this, ex);
 446  0
             ex.printStackTrace();
 447  0
             errorHandler.fatalError(saxException);
 448  0
         }
 449  0
     }
 450  
 
 451  
     /**
 452  
      * Calls {@link ContentHandler.startElement(String, String, String, Attributes) startElement}
 453  
      * on the <code>ContentHandler</code> with <code>this</code> driver object as the
 454  
      * {@link Attributes} implementation. In default implementation
 455  
      * {@link Attributes} object is valid only during this method call and may not
 456  
      * be stored. Sub-classes can overwrite this method to cache attributes.
 457  
      */
 458  
     protected void startElement(String namespace, String localName, String qName) throws SAXException {
 459  0
         contentHandler.startElement(namespace, localName, qName, this);
 460  0
     }
 461  
 
 462  
 }