Coverage Report - com.mattunderscore.http.headers.language.LanguageParser
 
Classes in this File Line Coverage Branch Coverage Complexity
LanguageParser
90%
47/52
82%
28/34
6.5
 
 1  
 /* Copyright © 2012, 2013 Matthew Champion
 2  
  All rights reserved.
 3  
 
 4  
  Redistribution and use in source and binary forms, with or without
 5  
  modification, are permitted provided that the following conditions are met:
 6  
  * Redistributions of source code must retain the above copyright
 7  
  notice, this list of conditions and the following disclaimer.
 8  
  * Redistributions in binary form must reproduce the above copyright
 9  
  notice, this list of conditions and the following disclaimer in the
 10  
  documentation and/or other materials provided with the distribution.
 11  
  * Neither the name of mattunderscore.com nor the
 12  
  names of its contributors may be used to endorse or promote products
 13  
  derived from this software without specific prior written permission.
 14  
 
 15  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 16  
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 17  
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 18  
  DISCLAIMED. IN NO EVENT SHALL MATTHEW CHAMPION BE LIABLE FOR ANY
 19  
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 20  
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 21  
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 22  
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 23  
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 24  
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
 25  
 
 26  
 package com.mattunderscore.http.headers.language;
 27  
 
 28  
 import java.util.ArrayList;
 29  
 import java.util.Collection;
 30  
 
 31  
 import com.mattunderscore.http.headers.HeaderFieldCollectionParser;
 32  
 import com.mattunderscore.http.headers.HeaderFieldNameVerifier;
 33  
 import com.mattunderscore.http.headers.UnParsableHeaderException;
 34  
 
 35  
 /**
 36  
  * Parse an accept-language field header string to a structured representation.
 37  
  * 
 38  
  * @author Matt Champion
 39  
  * @since 0.0.13
 40  
  */
 41  
 public class LanguageParser implements HeaderFieldCollectionParser<ILanguage>,
 42  
         HeaderFieldNameVerifier
 43  
 {
 44  
     private static final String HEADER_FIELD_NAME = "Accept-Language";
 45  
 
 46  
     public LanguageParser()
 47  70
     {
 48  70
     }
 49  
 
 50  
     @Override
 51  
     public boolean isHeaderFieldName(String header)
 52  
     {
 53  0
         return HEADER_FIELD_NAME.equalsIgnoreCase(header);
 54  
     }
 55  
 
 56  
     @Override
 57  
     public String getHeaderFieldName()
 58  
     {
 59  10
         return HEADER_FIELD_NAME;
 60  
     }
 61  
 
 62  
     @Override
 63  
     public Collection<ILanguage> parseElements(String header) throws UnParsableHeaderException
 64  
     {
 65  72
         if (header == null)
 66  
         {
 67  2
             throw new UnParsableHeaderException("Null Pointer.");
 68  
         }
 69  70
         Collection<ILanguage> qL = new ArrayList<ILanguage>();
 70  70
         if ("".equals(header))
 71  
         {
 72  2
             return qL;
 73  
         }
 74  68
         String[] types = header.split(",", -1);
 75  120
         for (int i = 0; i < types.length; i++)
 76  
         {
 77  86
             QLanguage lang = parseSingleElement(types[i].trim());
 78  52
             if (lang != null)
 79  
             {
 80  52
                 qL.add(lang);
 81  
             }
 82  
         }
 83  34
         return qL;
 84  
     }
 85  
 
 86  
     private QLanguage parseSingleElement(String types) throws UnParsableHeaderException
 87  
     {
 88  86
         if (types == null)
 89  
         {
 90  0
             throw new UnParsableHeaderException("Null Pointer.");
 91  
         }
 92  86
         if ("".equals(types.trim()))
 93  
         {
 94  2
             throw new UnParsableHeaderException("Empty string");
 95  
         }
 96  84
         final String[] langParts = types.trim().split("-");
 97  84
         double qualifier = 1.0;
 98  84
         if (langParts.length == 1)
 99  
         {
 100  38
             String[] lastParts = langParts[0].trim().split(";");
 101  38
             if (lastParts.length == 1)
 102  
             {
 103  16
                 qualifier = 1.0;
 104  
             }
 105  22
             else if (lastParts.length == 2)
 106  
             {
 107  22
                 qualifier = parseQualifier(lastParts[1]);
 108  
             }
 109  
             else
 110  
             {
 111  0
                 throw new UnParsableHeaderException("Incorrect number of parts.");
 112  
             }
 113  26
             return new QLanguage(lastParts[0].trim(), "*", qualifier);
 114  
         }
 115  46
         else if (langParts.length == 2)
 116  
         {
 117  42
             if (langParts[0].contains(";"))
 118  
             {
 119  2
                 throw new UnParsableHeaderException("Semicolon before dash");
 120  
             }
 121  
             else
 122  
             {
 123  40
                 final String[] lastParts = langParts[1].trim().split(";");
 124  40
                 if (lastParts.length == 1)
 125  
                 {
 126  10
                     qualifier = 1.0;
 127  
                 }
 128  30
                 else if (lastParts.length == 2)
 129  
                 {
 130  30
                     qualifier = parseQualifier(lastParts[1]);
 131  
                 }
 132  
                 else
 133  
                 {
 134  0
                     throw new UnParsableHeaderException("Incorrect number of parts.");
 135  
                 }
 136  26
                 return new QLanguage(langParts[0].trim(), lastParts[0].trim(), qualifier);
 137  
             }
 138  
         }
 139  
         else
 140  
         {
 141  4
             throw new UnParsableHeaderException("Unparsable language: " + types.trim() + ": "
 142  
                     + langParts.length);
 143  
         }
 144  
     }
 145  
 
 146  
     private double parseQualifier(String qualifierString) throws UnParsableHeaderException
 147  
     {
 148  52
         final String[] qualifierParts = qualifierString.trim().split("=");
 149  52
         if (qualifierParts.length == 2)
 150  
         {
 151  36
             if ("q".equals(qualifierParts[0].trim()))
 152  
             {
 153  
                 double qualifier;
 154  
                 try
 155  
                 {
 156  36
                     qualifier = Double.parseDouble(qualifierParts[1].trim());
 157  
                 }
 158  4
                 catch (NumberFormatException ex)
 159  
                 {
 160  4
                     throw new UnParsableHeaderException("Number format excetpion.");
 161  32
                 }
 162  32
                 if (qualifier < 0.0 || qualifier > 1.0)
 163  
                 {
 164  6
                     throw new UnParsableHeaderException("Invalid qualifier range.");
 165  
                 }
 166  26
                 return qualifier;
 167  
             }
 168  
             else
 169  
             {
 170  0
                 throw new UnParsableHeaderException("Unrecoginsed property");
 171  
             }
 172  
         }
 173  
         else
 174  
         {
 175  16
             throw new UnParsableHeaderException("Invalid property");
 176  
         }
 177  
     }
 178  
 }