Coverage Report - de.smartics.pmd.rules.strings.StringLiteralEncodingRule
 
Classes in this File Line Coverage Branch Coverage Complexity
StringLiteralEncodingRule
0%
0/22
0%
0/6
2
 
 1  
 /*
 2  
  * Copyright 2011-2013 smartics, Kronseder & Reiner GmbH
 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 de.smartics.pmd.rules.strings;
 17  
 
 18  
 import java.nio.ByteBuffer;
 19  
 import java.nio.CharBuffer;
 20  
 import java.nio.charset.CharacterCodingException;
 21  
 import java.nio.charset.Charset;
 22  
 import java.nio.charset.CharsetDecoder;
 23  
 
 24  
 import net.sourceforge.pmd.AbstractJavaRule;
 25  
 import net.sourceforge.pmd.PropertyDescriptor;
 26  
 import net.sourceforge.pmd.ast.ASTLiteral;
 27  
 import net.sourceforge.pmd.properties.StringProperty;
 28  
 
 29  
 /**
 30  
  * Rule to detect usage of characters of disallowed encoding in String literals.
 31  
  */
 32  0
 public class StringLiteralEncodingRule extends AbstractJavaRule
 33  
 {
 34  
   // ********************************* Fields *********************************
 35  
 
 36  
   // --- constants ------------------------------------------------------------
 37  
 
 38  
   /**
 39  
    * The descriptor to the {@link #encoding} property of this rule.
 40  
    */
 41  0
   private static final PropertyDescriptor ENCODING_DESCRIPTOR =
 42  
       new StringProperty("encoding",
 43  
           "The name of the allowed encoding for string literals.", "US-ASCII",
 44  
           1.0f);
 45  
 
 46  
   // --- members --------------------------------------------------------------
 47  
 
 48  
   /**
 49  
    * The allowed encoding.
 50  
    */
 51  
   private String encoding;
 52  
 
 53  
   /**
 54  
    * The decoder dependent on the {@link #encoding}.
 55  
    */
 56  
   private CharsetDecoder decoder;
 57  
 
 58  
   // ****************************** Initializer *******************************
 59  
 
 60  
   // ****************************** Constructors ******************************
 61  
 
 62  
   // ****************************** Inner Classes *****************************
 63  
 
 64  
   // ********************************* Methods ********************************
 65  
 
 66  
   // --- init -----------------------------------------------------------------
 67  
 
 68  
   // --- get&set --------------------------------------------------------------
 69  
 
 70  
   // --- business -------------------------------------------------------------
 71  
 
 72  
   /**
 73  
    * Checks that there are disallowed encoded characters in String literals.
 74  
    * {@inheritDoc}
 75  
    *
 76  
    * @see net.sourceforge.pmd.AbstractJavaRule#visit(net.sourceforge.pmd.ast.ASTLiteral,
 77  
    *      java.lang.Object)
 78  
    */
 79  
   @Override
 80  
   public Object visit(final ASTLiteral node, final Object data)
 81  
   {
 82  0
     provideRuleProperties();
 83  
 
 84  0
     if (node.isStringLiteral())
 85  
     {
 86  0
       final String literal = node.getImage();
 87  0
       if (!isProperlyEncoded(literal))
 88  
       {
 89  0
         final String message = createMessage(literal);
 90  0
         addViolationWithMessage(data, node, message);
 91  
       }
 92  
     }
 93  
 
 94  0
     return super.visit(node, data);
 95  
   }
 96  
 
 97  
   private String createMessage(final String literal)
 98  
   {
 99  0
     return "String literal '" + literal + "' is not encoded with '" + encoding
 100  
            + "'.";
 101  
   }
 102  
 
 103  
   private void provideRuleProperties()
 104  
   {
 105  0
     if (encoding == null)
 106  
     {
 107  0
       encoding = getStringProperty(ENCODING_DESCRIPTOR);
 108  0
       decoder = Charset.forName(encoding).newDecoder();
 109  
     }
 110  0
   }
 111  
 
 112  
   /**
 113  
    * Inspired by <a href=
 114  
    * "http://stackoverflow.com/questions/3585053/in-java-is-it-possible-to-check-if-a-string-is-only-ascii"
 115  
    * >In Java, is it possible to check if a String is only ASCII?</a>.
 116  
    */
 117  
   private boolean isProperlyEncoded(final String string)
 118  
   {
 119  0
     final byte[] stringBytes = string.getBytes();
 120  
 
 121  
     try
 122  
     {
 123  0
       final CharBuffer buffer = decoder.decode(ByteBuffer.wrap(stringBytes));
 124  0
       buffer.toString();
 125  
     }
 126  0
     catch (final CharacterCodingException e)
 127  
     {
 128  0
       return false;
 129  0
     }
 130  
 
 131  0
     return true;
 132  
   }
 133  
 
 134  
   // --- object basics --------------------------------------------------------
 135  
 
 136  
   /**
 137  
    * Returns the string representation of the class for debugging.
 138  
    *
 139  
    * @return the string representation of the class for debugging.
 140  
    */
 141  
   @Override
 142  
   public String toString()
 143  
   {
 144  0
     return "StringLiteralEncodingRule with encoding '" + encoding + "'.";
 145  
   }
 146  
 }