Coverage Report - org.apache.commons.i18n.XMLMessageProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
XMLMessageProvider
100%
36/36
100%
10/10
1.941
XMLMessageProvider$ConfigurationHandler
100%
22/22
94%
15/16
1.941
XMLMessageProvider$Message
100%
15/15
100%
6/6
1.941
 
 1  
 /*
 2  
 *
 3  
 * ====================================================================
 4  
 *
 5  
 * Licensed to the Apache Software Foundation (ASF) under one or more
 6  
 * contributor license agreements.  See the NOTICE file distributed with
 7  
 * this work for additional information regarding copyright ownership.
 8  
 * The ASF licenses this file to You under the Apache License, Version 2.0
 9  
 * (the "License"); you may not use this file except in compliance with
 10  
 * the License.  You may obtain a copy of the License at
 11  
 *
 12  
 *     http://www.apache.org/licenses/LICENSE-2.0
 13  
 *
 14  
 * Unless required by applicable law or agreed to in writing, software
 15  
 * distributed under the License is distributed on an "AS IS" BASIS,
 16  
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 17  
 * See the License for the specific language governing permissions and
 18  
 * limitations under the License.
 19  
 *
 20  
 */
 21  
 package org.apache.commons.i18n;
 22  
 
 23  
 import java.io.InputStream;
 24  
 import java.text.MessageFormat;
 25  
 import java.util.HashMap;
 26  
 import java.util.Locale;
 27  
 import java.util.Map;
 28  
 import java.util.logging.Level;
 29  
 import java.util.logging.Logger;
 30  
 
 31  
 import javax.xml.parsers.SAXParser;
 32  
 import javax.xml.parsers.SAXParserFactory;
 33  
 
 34  
 import org.xml.sax.Attributes;
 35  
 import org.xml.sax.InputSource;
 36  
 import org.xml.sax.helpers.DefaultHandler;
 37  
 
 38  
 /**
 39  
  * The <code>XMLMessageProvider</code> provides messages defined in an XML format.
 40  
  *  
 41  
  */
 42  29
 public class XMLMessageProvider implements MessageProvider {
 43  2
     private static final Logger logger = Logger.getLogger(XMLMessageProvider.class.getName());
 44  
 
 45  1
     private static SAXParserFactory factory = SAXParserFactory.newInstance();
 46  
     
 47  5
     private Map messages = new HashMap();
 48  
 
 49  5
     public XMLMessageProvider(InputStream inputStream) {
 50  
         try {
 51  5
             Map applicationMessages = new HashMap();
 52  5
             SAXParser parser = factory.newSAXParser();
 53  5
             ConfigurationHandler handler = new ConfigurationHandler();
 54  5
             parser.parse(new InputSource(inputStream), handler);
 55  4
             Map parsedMessages = handler.getMessages();
 56  4
             applicationMessages.putAll(parsedMessages);
 57  4
             messages.putAll(applicationMessages);
 58  1
         } catch (Exception exception) {
 59  1
             String msg = I18nUtils.INTERNAL_MESSAGES.getString(I18nUtils.MESSAGE_PARSING_ERROR);
 60  1
             logger.log(Level.SEVERE,msg,exception);
 61  1
             throw new RuntimeException(msg, exception);
 62  4
         }
 63  4
     }
 64  
 
 65  
     /* (non-Javadoc)
 66  
      * @see org.apache.commons.i18n.MessageProvider#getText(java.lang.String, java.lang.String, java.util.Locale)
 67  
      */
 68  
     public String getText(String id, String entry, Locale locale) throws MessageNotFoundException {
 69  25
         Message message = findMessage(id, locale);
 70  24
         return message.getEntry(entry);
 71  
     }
 72  
 
 73  
     /* (non-Javadoc)
 74  
      * @see org.apache.commons.i18n.MessageProvider#getEntries(java.lang.String, java.util.Locale)
 75  
      */
 76  
     public Map getEntries(String id, Locale locale) throws MessageNotFoundException {
 77  7
         Message message = findMessage(id, locale);
 78  6
         return message.getEntries();
 79  
     }
 80  
 
 81  
     private Message findMessage(String id, Locale locale) {
 82  32
         Message message = lookupMessage(id, locale);
 83  32
         if (message == null) {
 84  5
             message = lookupMessage(id, Locale.getDefault());
 85  
         }
 86  32
         if (message == null ) throw new MessageNotFoundException(
 87  
                 MessageFormat.format(
 88  
                         I18nUtils.INTERNAL_MESSAGES.getString(I18nUtils.NO_MESSAGE_ENTRIES_FOUND),
 89  
                         new String[] { id }));
 90  30
         return message;
 91  
     }
 92  
 
 93  
     private Message lookupMessage(String id, Locale locale) {
 94  37
         String key = id + '_' + locale.toString();
 95  37
         if (messages.containsKey(key)) return (Message)messages.get(key);
 96  22
         locale = I18nUtils.getParentLocale(locale);
 97  26
         while (locale != null) {
 98  19
             key = id + '_' + locale.toString();
 99  19
             if (messages.containsKey(key)) return (Message)messages.get(key);
 100  4
             locale = I18nUtils.getParentLocale(locale);
 101  4
         }
 102  7
         return null;
 103  
     }
 104  
 
 105  5
     class ConfigurationHandler extends DefaultHandler {
 106  
         private String id, key;
 107  
         private Message message;
 108  
         private StringBuffer cData;
 109  
 
 110  
         public void startElement(String namespaceUri, String localeName, String qName, Attributes attributes)  {
 111  82
             if (qName.matches("message")) {
 112  4
                 id = attributes.getValue("id");
 113  4
             } else if (qName.matches("locale")) {
 114  25
                 message = new Message(id);
 115  25
                 message.setLanguage(attributes.getValue("language"));
 116  25
                 message.setCountry(attributes.getValue("country"));
 117  25
                 message.setVariant(attributes.getValue("variant"));
 118  25
             } else if (qName.matches("entry")) {
 119  49
                 key = attributes.getValue("key");
 120  49
                 cData = new StringBuffer();
 121  
             }
 122  82
         }
 123  
         public void characters(char[] ch,
 124  
                 int start,
 125  
                 int length) {
 126  206
             if ( message != null && key != null && length > 0 ) {
 127  49
                 cData.append(ch, start, length);
 128  
             }
 129  206
         }
 130  
         
 131  
         public void endElement(String namespaceUri, String localeName, String qName) {
 132  82
             if (qName.matches("locale")) {
 133  25
                 messages.put(message.getKey(), message);
 134  25
             } else if (qName.matches("entry")) {
 135  49
                 message.addEntry(key, cData.toString());
 136  49
                 key = null;
 137  
             }
 138  82
         }
 139  
         
 140  
         Map getMessages() {
 141  4
             return messages;
 142  
         }
 143  
     }
 144  
 
 145  
     static class Message {
 146  
         private final String id;
 147  
         private String language, country, variant;
 148  25
         private Map entries = new HashMap();
 149  
 
 150  25
         public Message(String id) {
 151  25
             this.id = id;
 152  25
         }
 153  
 
 154  
         public void addEntry(String key, String value) {
 155  49
             entries.put(key, value);
 156  49
         }
 157  
 
 158  
         public String getEntry(String key) {
 159  24
             return (String)entries.get(key);
 160  
         }
 161  
 
 162  
         public Map getEntries() {
 163  6
             return entries;
 164  
         }
 165  
 
 166  
         public void setLanguage(String language) {
 167  25
             this.language = language;
 168  25
         }
 169  
 
 170  
         public void setCountry(String country) {
 171  25
             this.country = country;
 172  25
         }
 173  
 
 174  
         public void setVariant(String variant) {
 175  25
             this.variant = variant;
 176  25
         }
 177  
 
 178  
         public String getKey() {
 179  25
             return id + '_' + new Locale((language != null) ? language : "",
 180  
                     (country != null) ? country : "",
 181  
                     (variant != null) ? variant : "").toString();
 182  
         }
 183  
     }
 184  
 }