Coverage Report - de.smartics.properties.spi.core.constraint.jsr303.ConstraintPrettifier
 
Classes in this File Line Coverage Branch Coverage Complexity
ConstraintPrettifier
0%
0/53
0%
0/24
2.364
ConstraintPrettifier$1
N/A
N/A
N/A
N/A
2.364
ConstraintPrettifier$ParameterToken
0%
0/5
0%
0/8
2.364
 
 1  
 /*
 2  
  * Copyright 2012-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.properties.spi.core.constraint.jsr303;
 17  
 
 18  
 import java.lang.annotation.Annotation;
 19  
 import java.util.StringTokenizer;
 20  
 import java.util.regex.Matcher;
 21  
 import java.util.regex.Pattern;
 22  
 
 23  
 /**
 24  
  * A helper class to make JSR-303 constraints human readable in the context of
 25  
  * smartics properties.
 26  
  */
 27  
 final class ConstraintPrettifier
 28  
 {
 29  
   // ********************************* Fields *********************************
 30  
 
 31  
   // --- constants ------------------------------------------------------------
 32  
 
 33  
   /**
 34  
    * The pattern to match constraints in their native, typical
 35  
    * {@link Annotation#toString()} representation.
 36  
    */
 37  0
   private static final Pattern PATTERN = Pattern
 38  
       .compile("@([^(]+)\\(([^)]+)\\)");
 39  
 
 40  
   // --- members --------------------------------------------------------------
 41  
 
 42  
   /**
 43  
    * The annotation prettified by this instance.
 44  
    */
 45  
   private final Annotation annotation;
 46  
 
 47  
   /**
 48  
    * The prettified instance of the annotation.
 49  
    */
 50  
   private final String pretty;
 51  
 
 52  
   // ****************************** Initializer *******************************
 53  
 
 54  
   // ****************************** Constructors ******************************
 55  
 
 56  
   /**
 57  
    * Default constructor.
 58  
    *
 59  
    * @param annotation the annotation prettified by this instance.
 60  
    * @throws NullPointerException if {@code annotation} is <code>null</code>.
 61  
    */
 62  
   ConstraintPrettifier(final Annotation annotation) throws NullPointerException
 63  0
   {
 64  0
     this.pretty = prettify(annotation);
 65  0
     this.annotation = annotation;
 66  0
   }
 67  
 
 68  
   // ****************************** Inner Classes *****************************
 69  
 
 70  
   /**
 71  
    * A parameter token.
 72  
    */
 73  0
   private static final class ParameterToken
 74  
   {
 75  
     /**
 76  
      * The name of the token.
 77  
      */
 78  
     private String name;
 79  
 
 80  
     /**
 81  
      * Flag to check if the token a name/value pair.
 82  
      */
 83  
     private boolean isNameValue;
 84  
 
 85  
     /**
 86  
      * The original token.
 87  
      */
 88  
     private String token;
 89  
 
 90  
     private boolean isRelevantParameter()
 91  
     {
 92  0
       return !("message".equals(name) || "groups".equals(name) || "payload"
 93  
           .equals(name)) && !tokenIsEmptyArray();
 94  
     }
 95  
 
 96  
     private boolean tokenIsEmptyArray()
 97  
     {
 98  0
       return token.endsWith("=[]");
 99  
     }
 100  
 
 101  
     private void append(final StringBuilder buffer)
 102  
     {
 103  0
       buffer.append(' ').append(token.trim()).append(',');
 104  0
     }
 105  
   }
 106  
 
 107  
   // ********************************* Methods ********************************
 108  
 
 109  
   // --- init -----------------------------------------------------------------
 110  
 
 111  
   // --- get&set --------------------------------------------------------------
 112  
 
 113  
   private static String prettify(final Annotation annotation)
 114  
     throws NullPointerException
 115  
   {
 116  0
     final String plain = annotation.toString();
 117  
 
 118  0
     final Matcher matcher = PATTERN.matcher(plain);
 119  0
     if (matcher.matches())
 120  
     {
 121  0
       final StringBuilder buffer = new StringBuilder(128);
 122  0
       final String constraint = matcher.group(1);
 123  0
       addConstraint(buffer, constraint);
 124  0
       final String parameter = matcher.group(2);
 125  0
       addParameter(buffer, parameter);
 126  0
       return buffer.toString();
 127  
     }
 128  
     else
 129  
     {
 130  0
       return plain;
 131  
     }
 132  
   }
 133  
 
 134  
   private static void addConstraint(final StringBuilder buffer,
 135  
       final String constraint)
 136  
   {
 137  0
     final int index = constraint.lastIndexOf('.');
 138  0
     if (index > -1 && index < constraint.length() - 1)
 139  
     {
 140  0
       final String shortName = constraint.substring(index + 1);
 141  0
       buffer.append(shortName);
 142  0
     }
 143  
     else
 144  
     {
 145  0
       buffer.append(constraint);
 146  
     }
 147  0
   }
 148  
 
 149  
   private static void addParameter(final StringBuilder buffer,
 150  
       final String parameter)
 151  
   {
 152  0
     final int initialLength = buffer.length();
 153  0
     final StringTokenizer tokenizer = new StringTokenizer(parameter, ",");
 154  0
     while (tokenizer.hasMoreTokens())
 155  
     {
 156  0
       final ParameterToken token = fetchToken(tokenizer);
 157  0
       if (token.isNameValue)
 158  
       {
 159  0
         if (token.isRelevantParameter())
 160  
         {
 161  0
           token.append(buffer);
 162  
         }
 163  
       }
 164  
       else
 165  
       {
 166  0
         token.append(buffer);
 167  
       }
 168  0
     }
 169  
 
 170  0
     if (initialLength < buffer.length())
 171  
     {
 172  0
       buffer.setCharAt(initialLength, '(');
 173  0
       buffer.setCharAt(buffer.length() - 1, ')');
 174  
     }
 175  0
   }
 176  
 
 177  
   private static ParameterToken fetchToken(final StringTokenizer tokenizer)
 178  
   {
 179  0
     final ParameterToken result = new ParameterToken();
 180  
 
 181  0
     String token = tokenizer.nextToken();
 182  0
     final int index = token.indexOf('=');
 183  0
     result.isNameValue = index != -1;
 184  0
     if (result.isNameValue)
 185  
     {
 186  0
       final StringBuilder buffer = new StringBuilder(24);
 187  0
       if (token.charAt(index + 1) == '[')
 188  
       {
 189  0
         while (tokenizer.hasMoreTokens() && !token.endsWith("]"))
 190  
         {
 191  0
           buffer.append(token).append(',');
 192  0
           token = tokenizer.nextToken();
 193  
         }
 194  0
         buffer.append(token);
 195  0
         result.token = buffer.toString();
 196  
       }
 197  
       else
 198  
       {
 199  0
         result.token = token;
 200  
       }
 201  
 
 202  0
       result.name = result.token.substring(0, index).trim();
 203  
     }
 204  
 
 205  0
     return result;
 206  
   }
 207  
 
 208  
   /**
 209  
    * Returns the annotation prettified by this instance.
 210  
    *
 211  
    * @return the annotation prettified by this instance.
 212  
    */
 213  
   public Annotation getAnnotation()
 214  
   {
 215  0
     return annotation;
 216  
   }
 217  
 
 218  
   /**
 219  
    * Returns the prettified instance of the annotation.
 220  
    *
 221  
    * @return the prettified instance of the annotation.
 222  
    */
 223  
   public String getPretty()
 224  
   {
 225  0
     return pretty;
 226  
   }
 227  
 
 228  
   // --- business -------------------------------------------------------------
 229  
 
 230  
   // --- object basics --------------------------------------------------------
 231  
 
 232  
   @Override
 233  
   public String toString()
 234  
   {
 235  0
     return pretty;
 236  
   }
 237  
 }