Coverage Report - org.apache.commons.mail.EmailUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
EmailUtils
85%
57/67
57%
30/52
4.5
 
 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  
 
 18  
 package org.apache.commons.mail;
 19  
 
 20  
 import org.apache.commons.mail.util.MimeMessageUtils;
 21  
 
 22  
 import javax.mail.internet.MimeMessage;
 23  
 import javax.mail.MessagingException;
 24  
 
 25  
 import java.util.BitSet;
 26  
 import java.util.Random;
 27  
 import java.io.File;
 28  
 import java.io.IOException;
 29  
 import java.io.UnsupportedEncodingException;
 30  
 
 31  
 /**
 32  
  * Utility methods used by commons-email.
 33  
  *
 34  
  * <p>
 35  
  * These methods are copied from other commons components (commons-lang) to avoid creating
 36  
  * a dependency for such a small component.
 37  
  * </p>
 38  
  *
 39  
  * <p>
 40  
  * This is a package scoped class, and should not be used directly by users.
 41  
  * </p>
 42  
  *
 43  
  * @author jakarta-commons
 44  
  * @since 1.0
 45  
  * @version $Id: EmailUtils.java 1420381 2012-12-11 20:18:05Z tn $
 46  
  */
 47  
 final class EmailUtils
 48  
 {
 49  
     /**
 50  
      * Random object used by random method. This has to be not local to the random method
 51  
      * so as to not return the same value in the same millisecond.
 52  
      */
 53  4
     private static final Random RANDOM = new Random();
 54  
 
 55  
     /**
 56  
      * The default charset used for URL encoding.
 57  
      */
 58  
     private static final String US_ASCII = "US-ASCII";
 59  
 
 60  
     /**
 61  
      * Radix used in encoding.
 62  
      */
 63  
     private static final int RADIX = 16;
 64  
 
 65  
     /**
 66  
      * The escape character used for the URL encoding scheme.
 67  
      */
 68  
     private static final char ESCAPE_CHAR = '%';
 69  
 
 70  
     /**
 71  
      * BitSet of RFC 2392 safe URL characters.
 72  
      */
 73  4
     private static final BitSet SAFE_URL = new BitSet(256);
 74  
 
 75  
     // Static initializer for safe_uri
 76  
     static {
 77  
         // alpha characters
 78  108
         for (int i = 'a'; i <= 'z'; i++)
 79  
         {
 80  104
             SAFE_URL.set(i);
 81  
         }
 82  108
         for (int i = 'A'; i <= 'Z'; i++)
 83  
         {
 84  104
             SAFE_URL.set(i);
 85  
         }
 86  
         // numeric characters
 87  44
         for (int i = '0'; i <= '9'; i++)
 88  
         {
 89  40
             SAFE_URL.set(i);
 90  
         }
 91  
 
 92  
         // safe chars
 93  4
         SAFE_URL.set('-');
 94  4
         SAFE_URL.set('_');
 95  4
         SAFE_URL.set('.');
 96  4
         SAFE_URL.set('*');
 97  4
         SAFE_URL.set('+');
 98  4
         SAFE_URL.set('$');
 99  4
         SAFE_URL.set('!');
 100  4
         SAFE_URL.set('\'');
 101  4
         SAFE_URL.set('(');
 102  4
         SAFE_URL.set(')');
 103  4
         SAFE_URL.set(',');
 104  4
         SAFE_URL.set('@');
 105  4
     }
 106  
 
 107  
     /**
 108  
      * Constructs a new <code>EmailException</code> with no detail message.
 109  
      */
 110  
     private EmailUtils()
 111  
     {
 112  0
         super();
 113  0
     }
 114  
 
 115  
     /**
 116  
      * Checks if a String is empty ("") or null.
 117  
      *
 118  
      * @param str the String to check, may be null
 119  
      *
 120  
      * @return <code>true</code> if the String is empty or null
 121  
      *
 122  
      * @since Commons Lang v2.1, svn 240418
 123  
      */
 124  
     static boolean isEmpty(String str)
 125  
     {
 126  518
         return (str == null) || (str.length() == 0);
 127  
     }
 128  
 
 129  
     /**
 130  
      * Checks if a String is not empty ("") and not null.
 131  
      *
 132  
      * @param str the String to check, may be null
 133  
      *
 134  
      * @return <code>true</code> if the String is not empty and not null
 135  
      *
 136  
      * @since Commons Lang v2.1, svn 240418
 137  
      */
 138  
     static boolean isNotEmpty(String str)
 139  
     {
 140  498
         return (str != null) && (str.length() > 0);
 141  
     }
 142  
 
 143  
     /**
 144  
      * Validate an argument, throwing <code>IllegalArgumentException</code>
 145  
      * if the argument is <code>null</code>.
 146  
      *
 147  
      * @param object the object to check is not <code>null</code>
 148  
      * @param message the exception message you would like to see if the object is <code>null</code>
 149  
      *
 150  
      * @throws IllegalArgumentException if the object is <code>null</code>
 151  
      *
 152  
      * @since Commons Lang v2.1, svn 201930
 153  
      */
 154  
     static void notNull(Object object, String message)
 155  
     {
 156  29
         if (object == null)
 157  
         {
 158  0
             throw new IllegalArgumentException(message);
 159  
         }
 160  29
     }
 161  
 
 162  
     /**
 163  
      * Creates a random string whose length is the number of characters specified.
 164  
      *
 165  
      * <p>
 166  
      * Characters will be chosen from the set of alphabetic characters.
 167  
      * </p>
 168  
      *
 169  
      * @param count the length of random string to create
 170  
      *
 171  
      * @return the random string
 172  
      *
 173  
      * @since Commons Lang v2.1, svn 201930
 174  
      */
 175  
     static String randomAlphabetic(int count)
 176  
     {
 177  35
         return random(count, 0, 0, true, false, null, RANDOM);
 178  
     }
 179  
 
 180  
     /**
 181  
      * Creates a random string based on a variety of options, using supplied source of randomness.
 182  
      *
 183  
      * <p>
 184  
      * If start and end are both <code>0</code>, start and end are set to <code>' '</code> and <code>'z'</code>,
 185  
      * the ASCII printable characters, will be used, unless letters and numbers are both <code>false</code>,
 186  
      * in which case, start and end are set to <code>0</code> and <code>Integer.MAX_VALUE</code>.
 187  
      * </p>
 188  
      *
 189  
      * <p>
 190  
      * If set is not <code>null</code>, characters between start and end are chosen.
 191  
      * </p>
 192  
      *
 193  
      * <p>
 194  
      * This method accepts a user-supplied {@link Random} instance to use as a source of randomness. By seeding a
 195  
      * single {@link Random} instance with a fixed seed and using it for each call, the same random sequence of strings
 196  
      * can be generated repeatedly and predictably.
 197  
      * </p>
 198  
      *
 199  
      * @param count the length of random string to create
 200  
      * @param start the position in set of chars to start at
 201  
      * @param end the position in set of chars to end before
 202  
      * @param letters only allow letters?
 203  
      * @param numbers only allow numbers?
 204  
      * @param chars the set of chars to choose randoms from. If <code>null</code>,
 205  
      *              then it will use the set of all chars.
 206  
      * @param random a source of randomness.
 207  
      *
 208  
      * @return the random string
 209  
      *
 210  
      * @throws IllegalArgumentException if <code>count</code> &lt; 0.
 211  
      *
 212  
      * @since Commons Lang v2.1, svn 201930
 213  
      */
 214  
     private static String random(
 215  
         int count,
 216  
         int start,
 217  
         int end,
 218  
         boolean letters,
 219  
         boolean numbers,
 220  
         char [] chars,
 221  
         Random random)
 222  
     {
 223  35
         if (count == 0)
 224  
         {
 225  0
             return "";
 226  
         }
 227  35
         else if (count < 0)
 228  
         {
 229  0
             throw new IllegalArgumentException("Requested random string length " + count + " is less than 0.");
 230  
         }
 231  
 
 232  35
         if ((start == 0) && (end == 0))
 233  
         {
 234  35
             end = 'z' + 1;
 235  35
             start = ' ';
 236  
 
 237  35
             if (!letters && !numbers)
 238  
             {
 239  0
                 start = 0;
 240  0
                 end = Integer.MAX_VALUE;
 241  
             }
 242  
         }
 243  
 
 244  35
         StringBuffer buffer = new StringBuffer();
 245  35
         int gap = end - start;
 246  
 
 247  647
         while (count-- != 0)
 248  
         {
 249  
             char ch;
 250  
 
 251  612
             if (chars == null)
 252  
             {
 253  612
                 ch = (char) (random.nextInt(gap) + start);
 254  
             }
 255  
             else
 256  
             {
 257  0
                 ch = chars[random.nextInt(gap) + start];
 258  
             }
 259  
 
 260  612
             if ((letters && numbers && Character.isLetterOrDigit(ch)) || (letters && Character.isLetter(ch))
 261  
                             || (numbers && Character.isDigit(ch)) || (!letters && !numbers))
 262  
             {
 263  350
                 buffer.append(ch);
 264  
             }
 265  
             else
 266  
             {
 267  262
                 count++;
 268  
             }
 269  612
         }
 270  
 
 271  35
         return buffer.toString();
 272  
     }
 273  
 
 274  
     /**
 275  
      * Encodes an input string according to RFC 2392. Unsafe characters are escaped.
 276  
      *
 277  
      * @param input the input string to be URL encoded
 278  
      * @return a URL encoded string
 279  
      * @throws UnsupportedEncodingException if "US-ASCII" charset is not available
 280  
      * @see <a href="http://tools.ietf.org/html/rfc2392">RFC 2392</a>
 281  
      */
 282  
     static String encodeUrl(final String input) throws UnsupportedEncodingException
 283  
     {
 284  47
         if (input == null)
 285  
         {
 286  0
             return null;
 287  
         }
 288  
 
 289  47
         final StringBuilder buffer = new StringBuilder();
 290  546
         for (byte c : input.getBytes(US_ASCII))
 291  
         {
 292  499
             int b = c;
 293  499
             if (b < 0)
 294  
             {
 295  0
                 b = 256 + b;
 296  
             }
 297  499
             if (SAFE_URL.get(b))
 298  
             {
 299  484
                 buffer.append((char) b);
 300  
             }
 301  
             else
 302  
             {
 303  15
                 buffer.append(ESCAPE_CHAR);
 304  15
                 char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, RADIX));
 305  15
                 char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, RADIX));
 306  15
                 buffer.append(hex1);
 307  15
                 buffer.append(hex2);
 308  
             }
 309  
         }
 310  47
         return buffer.toString();
 311  
     }
 312  
 
 313  
     /**
 314  
      * Convenience method to write a MimeMessage into a file.
 315  
      *
 316  
      * @param resultFile the file containing the MimeMessgae
 317  
      * @param mimeMessage the MimeMessage to write
 318  
      * @throws IOException writing the MimeMessage failed
 319  
      * @throws MessagingException writing the MimeMessage failed
 320  
      */
 321  
     static void writeMimeMessage(File resultFile, MimeMessage mimeMessage) throws IOException, MessagingException
 322  
     {
 323  39
         MimeMessageUtils.writeMimeMessage(mimeMessage, resultFile);
 324  39
     }
 325  
 }