Coverage Report - us.paulevans.basicxslt.Utils
 
Classes in this File Line Coverage Branch Coverage Complexity
Utils
0%
0/138
0%
0/18
0
 
 1  
 /*
 2  
         Copyright 2006 Paul Evans
 3  
 
 4  
         Licensed under the Apache License, Version 2.0 (the "License"); 
 5  
         you may not use this file except in compliance with the License. 
 6  
         You may obtain a copy of the License at 
 7  
 
 8  
                 http://www.apache.org/licenses/LICENSE-2.0 
 9  
 
 10  
         Unless required by applicable law or agreed to in writing, software 
 11  
         distributed under the License is distributed on an "AS IS" BASIS, 
 12  
         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 13  
         See the License for the specific language governing permissions and 
 14  
         limitations under the License.
 15  
  */
 16  
 package us.paulevans.basicxslt;
 17  
 
 18  
 import java.awt.Component;
 19  
 import java.awt.Cursor;
 20  
 import java.awt.Frame;
 21  
 import java.io.Closeable;
 22  
 import java.io.File;
 23  
 import java.io.FileInputStream;
 24  
 import java.io.FileOutputStream;
 25  
 import java.io.IOException;
 26  
 import java.io.OutputStream;
 27  
 import java.net.SocketException;
 28  
 import java.net.UnknownHostException;
 29  
 import java.text.MessageFormat;
 30  
 import java.util.List;
 31  
 
 32  
 import javax.swing.JFileChooser;
 33  
 import javax.swing.JOptionPane;
 34  
 import javax.xml.parsers.ParserConfigurationException;
 35  
 import javax.xml.parsers.SAXParser;
 36  
 import javax.xml.parsers.SAXParserFactory;
 37  
 import javax.xml.transform.SourceLocator;
 38  
 import javax.xml.transform.TransformerConfigurationException;
 39  
 import javax.xml.transform.TransformerException;
 40  
 
 41  
 import org.apache.commons.lang.StringUtils;
 42  
 import org.apache.commons.lang.SystemUtils;
 43  
 import org.apache.commons.lang.exception.ExceptionUtils;
 44  
 import org.apache.log4j.Logger;
 45  
 import org.xml.sax.SAXException;
 46  
 import org.xml.sax.SAXNotRecognizedException;
 47  
 import org.xml.sax.SAXNotSupportedException;
 48  
 import org.xml.sax.SAXParseException;
 49  
 import org.xml.sax.helpers.DefaultHandler;
 50  
 
 51  
 /**
 52  
  * Contains many helper activities and also serves as an event-handler for 
 53  
  * SAX events (for XML validation).
 54  
  * @author pevans
 55  
  *
 56  
  */
 57  
 public class Utils extends DefaultHandler {
 58  
         
 59  
         // XML parser features...
 60  
         private static final String VALIDATION_FEATURE = 
 61  
                 "http://xml.org/sax/features/validation";
 62  
     private static final String SCHEMA_FEATURE = 
 63  
             "http://apache.org/xml/features/validation/schema";
 64  
     
 65  
         // static constant...
 66  0
     private static final JFileChooser FILE_CHOOSER = new JFileChooser();
 67  
     
 68  
     // singleton instance...
 69  0
     private static final Utils instance = new Utils();
 70  
     
 71  
         // get the i18n factory singleton instance...
 72  0
         private static final LabelStringFactory stringFactory = 
 73  
                 LabelStringFactory.getInstance();
 74  
     
 75  
     // static user preferences object...
 76  
     private static UserPreferences userPrefs;
 77  
     
 78  
     // logger object...
 79  0
     private static final Logger logger = Logger.getLogger(Utils.class);
 80  
     
 81  
     // instance members...
 82  
     private boolean checkWarning;
 83  
     private boolean checkError;
 84  
     private boolean checkFatalError;
 85  
 
 86  
     /**
 87  
      * private class constructor
 88  
      */
 89  0
     private Utils() {
 90  
             // does nothing...
 91  0
     }
 92  
     
 93  
     /**
 94  
      * Enables/disables the collection of aComponents
 95  
      * @param aComponents
 96  
      * @param aEnable
 97  
      */
 98  
     public static void setEnabled(List aComponents, boolean aEnable) {
 99  
             
 100  
             int size, loop;
 101  
             
 102  0
             size = aComponents.size();
 103  0
             for (loop = 0; loop < size; loop++) {
 104  0
                     ((Component)aComponents.get(loop)).setEnabled(aEnable);
 105  
             }
 106  0
     }
 107  
     
 108  
     /**
 109  
      * Builds and returns a JFileChooser - the current directory of the 
 110  
      * JFileChooser is determined from the user-prefs properties file.
 111  
      * @return JFileChooser
 112  
      * @throws Exception
 113  
      */
 114  
     public JFileChooser getFileChooser() throws IOException {
 115  
             
 116  
         String file;
 117  
         
 118  0
         file = Utils.getUserPrefs().getProperty(
 119  
                         AppConstants.LAST_FILE_CHOSEN_PROP);
 120  0
         if (StringUtils.isBlank(file)) {
 121  0
             file = "/"; 
 122  
         }
 123  0
         FILE_CHOOSER.setCurrentDirectory(new File(file));
 124  0
         return FILE_CHOOSER;
 125  
     }
 126  
     
 127  
     /**
 128  
      * Displays a message dialog
 129  
      * @param aParent
 130  
      * @param aMsg
 131  
      * @param aTitle
 132  
      * @param aType
 133  
      */
 134  
     public static void showDialog(Frame aParent, String aMsg, String aTitle,
 135  
             int aType) {
 136  0
             aParent.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 137  0
                 JOptionPane.showMessageDialog(aParent, aMsg, aTitle, aType);
 138  0
     }
 139  
     
 140  
     /**
 141  
      * Displays an error dialog
 142  
      * @param aParent
 143  
      * @param aThrowable
 144  
      */
 145  
     public static void showErrorDialog(Frame aParent, Throwable aThrowable) {
 146  
             
 147  
             String message;
 148  
             Throwable throwableToReport;
 149  
             
 150  0
             throwableToReport = ExceptionUtils.getRootCause(aThrowable);
 151  0
             if (throwableToReport == null) {
 152  0
                     throwableToReport = aThrowable;
 153  
             }
 154  0
             message = throwableToReport.getMessage();
 155  0
             if (StringUtils.isBlank(message)) {
 156  0
                     message = ExceptionUtils.getStackTrace(throwableToReport);
 157  
             }
 158  0
             if (aParent != null) {
 159  0
                     aParent.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 160  
             }
 161  0
             JOptionPane.showMessageDialog(aParent, MessageFormat.format(
 162  
                             stringFactory.getString(LabelStringFactory.ERRORS_MESSAGE), 
 163  
                             message, AppConstants.BUG_HOME_URL), 
 164  
                             stringFactory.getString(LabelStringFactory.ERRORS_TITLE), 
 165  
                                             JOptionPane.ERROR_MESSAGE);
 166  0
     }
 167  
 
 168  
     /**
 169  
      * Retrieves the user preferences from disk.
 170  
      * @return Properties
 171  
      * @throws Exception
 172  
      */
 173  
     public synchronized static UserPreferences getUserPrefs() {
 174  
             
 175  
             FileInputStream in;
 176  
                 File appPrefsDir, appPrefsFile;
 177  
                 
 178  0
             if (userPrefs == null) {
 179  0
                         userPrefs = new UserPreferences();
 180  0
                         in = null;
 181  
                         try {
 182  0
                                 appPrefsDir = new File(SystemUtils.USER_HOME + "/" + 
 183  
                                         AppConstants.APP_PREFS_DIR);
 184  0
                                 appPrefsDir.mkdir();
 185  0
                                 appPrefsFile = new File(appPrefsDir, 
 186  
                                                 AppConstants.APP_PREFS_FILE);
 187  0
                                 appPrefsFile.createNewFile();
 188  0
                                 userPrefs.load(in = new FileInputStream(appPrefsFile));
 189  0
                         } catch (IOException aException) {
 190  0
                                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 191  0
                                 Utils.showErrorDialog(null, aException);
 192  
                         } finally {
 193  0
                                 closeQuietly(in);
 194  0
                         }
 195  
             }                
 196  0
         return userPrefs;
 197  
     } 
 198  
     
 199  
     /**
 200  
      * Closes the inputted closeable object.
 201  
      * @param aCloseable
 202  
      */
 203  
     public static final void closeQuietly(Closeable aCloseable) {
 204  0
             if (aCloseable != null) {
 205  
                     try {
 206  0
                                 aCloseable.close();
 207  0
                         } catch (IOException e) {
 208  0
                                 logger.error(ExceptionUtils.getFullStackTrace(e));
 209  0
                         }
 210  
             }
 211  0
     }
 212  
 
 213  
     /**
 214  
      * Returns an output stream from the user prefs properties file.
 215  
      * @return OutputStream
 216  
      * @throws Exception
 217  
      */
 218  
     public static OutputStream getUserPrefsOutputStream() throws IOException {
 219  
             
 220  
         File appPrefsDir;
 221  
         
 222  
         try {
 223  0
                 appPrefsDir = new File(SystemUtils.USER_HOME + "/" + 
 224  
                                 AppConstants.APP_PREFS_DIR);
 225  0
                 appPrefsDir.mkdir();
 226  0
                 return new FileOutputStream(new File(appPrefsDir, 
 227  
                                 AppConstants.APP_PREFS_FILE));
 228  0
         } catch (IOException aException) {
 229  
                 // log and re-throw...
 230  0
                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 231  0
                 throw aException;
 232  
         }
 233  
     }
 234  
 
 235  
     /**
 236  
      * Returns the singleton instance
 237  
      * @return Utils
 238  
      */
 239  
     public static Utils getInstance() {
 240  0
         return instance;
 241  
     }
 242  
     
 243  
     /**
 244  
      * Returns aXSLRows as an array
 245  
      * @param aXSLRows
 246  
      * @return
 247  
      */
 248  
     public static XSLRow[] toArray(List<XSLRow> aXSLRows) {
 249  0
             return aXSLRows.toArray(new XSLRow[aXSLRows.size()]);
 250  
     }
 251  
 
 252  
     /**
 253  
      * Error handler - displays exception stack trace in a 
 254  
      * ValidationErrorFrame.
 255  
      * @param aTitle
 256  
      * @param aHeaderLabel
 257  
      * @param aHeader
 258  
      * @param aFileName
 259  
      * @param aParent
 260  
      * @param aThrowable
 261  
      * @throws IOException
 262  
      */
 263  
     public static void handleXMLError(String aTitle, String aHeaderLabel, 
 264  
                     String aHeader, String aFileName, BasicXSLTFrame aParent, 
 265  
                     Throwable aThrowable) {
 266  
             
 267  
         Error error;
 268  
         
 269  0
         logger.info("XML error: " + aThrowable.getMessage());
 270  0
         error = getErrorDetail(aThrowable);
 271  0
         new ValidationErrorFrame(aParent, aTitle, aHeaderLabel, aHeader, 
 272  
                         error.getColumn(), error.getLine(), error.getMessage(), 
 273  
                                 aFileName, null); 
 274  0
     }
 275  
     
 276  
     /**
 277  
      * Error handler
 278  
      * @param aTitle
 279  
      * @param aHeaderLabel
 280  
      * @param aHeader
 281  
      * @param aFileName
 282  
      * @param aParent
 283  
      * @param aMessage
 284  
      */
 285  
     public static void handleXMLError(String aTitle, String aHeaderLabel, 
 286  
                     String aHeader, String aFileName, BasicXSLTFrame aParent, 
 287  
                     String aMessage) {
 288  0
             logger.info("XML error: " + aMessage);
 289  0
         new ValidationErrorFrame(aParent, aTitle, aHeaderLabel, aHeader, 
 290  
                         -1, -1, aMessage, 
 291  
                                 aFileName, null); 
 292  0
     }
 293  
 
 294  
     /**
 295  
      * This method gets line and column info about the inputted throwable.
 296  
      * @return Error
 297  
      */
 298  
     public static Error getErrorDetail(Throwable aThrowable) {
 299  
             
 300  
             String errText;
 301  
             SourceLocator sourceLocator;
 302  
         Throwable root;
 303  
         int column, line;
 304  
         
 305  0
         errText = "";
 306  0
         column = -1;
 307  0
         line = -1;
 308  0
         if ((root = ExceptionUtils.getRootCause(aThrowable)) != null) {
 309  0
                 aThrowable = root;                
 310  
         }
 311  0
         if (aThrowable instanceof SAXParseException) {
 312  0
                 SAXParseException e = (SAXParseException)aThrowable;
 313  0
                 column = e.getColumnNumber();
 314  0
                 line = e.getLineNumber();
 315  0
             errText = e.getMessage();
 316  0
         } else if (aThrowable instanceof TransformerConfigurationException) {
 317  0
                 TransformerConfigurationException e = 
 318  
                         (TransformerConfigurationException)aThrowable;
 319  0
                 sourceLocator = e.getLocator();
 320  0
             if (sourceLocator != null) {
 321  0
                     column = sourceLocator.getColumnNumber();
 322  0
                                 line = sourceLocator.getLineNumber();
 323  0
                 errText = e.getMessage();
 324  0
             } else {
 325  0
                     errText = e.getMessageAndLocation();
 326  
             }
 327  0
         } else if (aThrowable instanceof TransformerException) {
 328  0
                 TransformerException e = (TransformerException)aThrowable;
 329  0
             sourceLocator = e.getLocator();
 330  0
             if (sourceLocator != null) {
 331  0
                     column = sourceLocator.getColumnNumber();
 332  0
                                 line = sourceLocator.getLineNumber();
 333  0
                 errText = e.getMessage();
 334  0
             } else {
 335  0
                     errText = e.getMessageAndLocation();
 336  
             }
 337  
         }
 338  0
         if (StringUtils.isBlank(errText)) {
 339  0
                 errText = ExceptionUtils.getStackTrace(aThrowable);
 340  
         }
 341  0
         return new Error(column, line, errText);
 342  
     }
 343  
     
 344  
     
 345  
 
 346  
     /**
 347  
      * Method to determine if inputted xml file is valid and well-formed.
 348  
      * @param saXmlFile
 349  
      * @throws Exception If saXmlFile is invalid or not well-formed.
 350  
      */
 351  
     public void isValidXml(File faXmlFile, boolean aCheckWarning,
 352  
                                   boolean aCheckError, 
 353  
                                                                   boolean aCheckFatalError) throws 
 354  
                                                                   SAXNotSupportedException, 
 355  
                                                                   SAXNotRecognizedException, 
 356  
                                                                   ParserConfigurationException, SAXException, 
 357  
                                                                   IOException {
 358  
             
 359  
             SAXParserFactory factory;
 360  
             
 361  0
         checkWarning = aCheckWarning;
 362  0
         checkError = aCheckError;
 363  0
         checkFatalError = aCheckFatalError;
 364  0
         if (faXmlFile.exists()) {  
 365  0
                 factory = SAXParserFactory.newInstance();
 366  0
                         factory.setValidating(true);
 367  0
                         factory.setNamespaceAware(true); 
 368  
                         try {
 369  0
                                 factory.setFeature(VALIDATION_FEATURE, true);
 370  0
                                 factory.setFeature(SCHEMA_FEATURE, true);               
 371  0
                                 SAXParser parser = factory.newSAXParser();    
 372  0
                                 parser.parse(faXmlFile, this);
 373  0
                         } catch (UnknownHostException aException) {
 374  
                                 // log and re-throw runtime exception...
 375  0
                                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 376  0
                                 throw new UnknownHostException(stringFactory.getString(
 377  
                                                 LabelStringFactory.ERRORS_NETWORK_CONNECT));
 378  0
                         } catch (SocketException aException) {
 379  
                                 // log and re-throw runtime exception...
 380  0
                                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 381  0
                                 throw new SocketException(stringFactory.getString(
 382  
                                                 LabelStringFactory.ERRORS_NETWORK_CONNECT));
 383  0
                         } catch (SAXNotSupportedException aException) {
 384  
                                 // log and re-throw...
 385  0
                                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 386  0
                                 throw aException;
 387  0
                         } catch (SAXNotRecognizedException aException) {
 388  
                                 // log and re-throw...
 389  0
                                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 390  0
                                 throw aException;
 391  0
                         } catch (ParserConfigurationException aException) {
 392  
                                 // log and re-throw...
 393  0
                                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 394  0
                                 throw aException;
 395  0
                         } catch (SAXException aException) {
 396  
                                 // log and re-throw...
 397  0
                                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 398  0
                                 throw aException;
 399  0
                         } catch (IOException aException) {
 400  
                                 // log and re-throw...
 401  0
                                 logger.error(ExceptionUtils.getFullStackTrace(aException));
 402  0
                                 throw aException;
 403  0
                         }
 404  
         } else {
 405  0
                 throw new RuntimeException(MessageFormat.format(
 406  
                                 stringFactory.getString(
 407  
                                                 LabelStringFactory.UTILS_FILE_DOES_NOT_EXIST), 
 408  
                                                 faXmlFile));
 409  
         }
 410  0
     }
 411  
 
 412  
     /**
 413  
      * Throws exception if 'checkWarning' is true when this method is called.
 414  
      * @param aException
 415  
      * @throws SAXException
 416  
      */
 417  
     public void warning(SAXParseException aException) throws SAXException {
 418  0
         if (checkWarning) {
 419  0
             throw aException;
 420  
         }
 421  0
     }
 422  
 
 423  
     /**
 424  
      * Throws exception if 'checkError' is true when this method is called.
 425  
      * @param aException
 426  
      * @throws SAXException
 427  
      */
 428  
     public void error(SAXParseException aException) throws SAXException {
 429  0
         if (checkError) {
 430  0
             throw aException;
 431  
         }
 432  0
     }
 433  
 
 434  
     /**
 435  
      * Throws exception if 'checkFatalError' is true when this method is called.
 436  
      * @param aException
 437  
      * @throws SAXException
 438  
      */
 439  
     public void fatalError(SAXParseException aException) throws SAXException {
 440  0
         if (checkFatalError) {
 441  0
             throw aException;
 442  
         }
 443  0
     } 
 444  
 }