Coverage Report - de.smartics.properties.spi.config.definition.DefinitionConfigParser
 
Classes in this File Line Coverage Branch Coverage Complexity
DefinitionConfigParser
0%
0/82
0%
0/22
2,818
 
 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.config.definition;
 17  
 
 18  
 import java.io.BufferedInputStream;
 19  
 import java.io.IOException;
 20  
 import java.io.InputStream;
 21  
 import java.net.URL;
 22  
 import java.util.HashMap;
 23  
 import java.util.HashSet;
 24  
 import java.util.List;
 25  
 import java.util.Map;
 26  
 import java.util.Set;
 27  
 
 28  
 import org.apache.commons.io.IOUtils;
 29  
 import org.apache.commons.lang.StringUtils;
 30  
 import org.jdom.Document;
 31  
 import org.jdom.Element;
 32  
 import org.jdom.JDOMException;
 33  
 import org.jdom.Namespace;
 34  
 import org.jdom.input.SAXBuilder;
 35  
 
 36  
 import de.smartics.properties.api.config.domain.key.ApplicationId;
 37  
 import de.smartics.properties.api.config.domain.key.ConfigurationKey;
 38  
 import de.smartics.properties.api.config.domain.key.EnvironmentId;
 39  
 import de.smartics.properties.api.core.domain.ConfigException;
 40  
 import de.smartics.properties.api.core.domain.PropertiesContext;
 41  
 import de.smartics.properties.spi.core.util.ClassLoaderUtils;
 42  
 import de.smartics.util.lang.ClassPathContext;
 43  
 import de.smartics.util.lang.NullArgumentException;
 44  
 
 45  
 /**
 46  
  * Parses the <code>definition.xml</code> file for properties.
 47  
  */
 48  
 public final class DefinitionConfigParser
 49  
 {
 50  
   // ********************************* Fields *********************************
 51  
 
 52  
   // --- constants ------------------------------------------------------------
 53  
 
 54  
   // --- members --------------------------------------------------------------
 55  
 
 56  
   /**
 57  
    * The namespace of definition files parsed by this parser.
 58  
    */
 59  0
   private static final Namespace NS = Namespace
 60  
       .getNamespace("http://smartics.de/properties/definition/1");
 61  
 
 62  
   // ****************************** Initializer *******************************
 63  
 
 64  
   // ****************************** Constructors ******************************
 65  
 
 66  
   // ****************************** Inner Classes *****************************
 67  
 
 68  
   // ********************************* Methods ********************************
 69  
 
 70  
   // --- init -----------------------------------------------------------------
 71  
 
 72  
   // --- get&set --------------------------------------------------------------
 73  
 
 74  
   // --- business -------------------------------------------------------------
 75  
 
 76  
   /**
 77  
    * Default constructor.
 78  
    */
 79  
   public DefinitionConfigParser()
 80  0
   {
 81  0
   }
 82  
 
 83  
   // --- object basics --------------------------------------------------------
 84  
 
 85  
   /**
 86  
    * Convenience method using a class' class loader to locate the configuration
 87  
    * file to parse the configuration file at
 88  
    * {@link PropertiesContext#DEFINITION_FILE}.
 89  
    *
 90  
    * @param type the type whose class loader to use to locate the configuration
 91  
    *          file.
 92  
    * @return the read configuration, never <code>null</code>.
 93  
    * @throws ConfigException on any problem loading the file.
 94  
    */
 95  
   public PropertiesDefinitionContext parse(final Class<?> type)
 96  
     throws ConfigException
 97  
   {
 98  0
     final ClassLoader loader = type.getClassLoader();
 99  0
     final String path = ClassLoaderUtils.calcArchivePath(type);
 100  0
     return parse(new ClassPathContext(loader, path));
 101  
   }
 102  
 
 103  
   /**
 104  
    * Parses the configuration file at {@link PropertiesContext#DEFINITION_FILE}.
 105  
    *
 106  
    * @param context the class loader with its context to use to locate the
 107  
    *          configuration file.
 108  
    * @return the read configuration, never <code>null</code>.
 109  
    * @throws ConfigException on any problem loading the file.
 110  
    */
 111  
   public PropertiesDefinitionContext parse(final ClassPathContext context)
 112  
     throws ConfigException
 113  
   {
 114  0
     final URL url = context.getResource(PropertiesContext.DEFINITION_FILE);
 115  0
     if (url != null)
 116  
     {
 117  0
       final String systemId = url.toExternalForm();
 118  0
       InputStream in = null;
 119  
       try
 120  
       {
 121  0
         in =
 122  
             new BufferedInputStream(
 123  
                 context.getResourceAsStream(PropertiesContext.DEFINITION_FILE));
 124  0
         return parse(systemId, in);
 125  
       }
 126  
       finally
 127  
       {
 128  0
         IOUtils.closeQuietly(in);
 129  
       }
 130  
     }
 131  0
     throw new ConfigException(PropertiesContext.DEFINITION_FILE);
 132  
   }
 133  
 
 134  
   /**
 135  
    * Parses the <code>definition.xml</code> from the given stream.
 136  
    *
 137  
    * @param systemId the identifier of the resource on the stream.
 138  
    * @param input the <code>definition.xml</code> on the stream.
 139  
    * @return the parsed context.
 140  
    * @throws ConfigException on any problem reading from the stream.
 141  
    */
 142  
   public PropertiesDefinitionContext parse(final String systemId,
 143  
       final InputStream input) throws ConfigException
 144  
   {
 145  
     try
 146  
     {
 147  0
       final SAXBuilder parser = new SAXBuilder();
 148  0
       final Document document = parser.build(input, systemId);
 149  
 
 150  0
       final Element rootNode = document.getRootElement();
 151  0
       final Set<String> tlds = readSet(rootNode, "tlds", "tld", null);
 152  0
       final Set<String> environments =
 153  
           readSet(rootNode, "environments", "environment");
 154  0
       final Set<String> nodes = readSet(rootNode, "nodes", "node");
 155  0
       final Set<String> groups = readSet(rootNode, "groups", "group");
 156  0
       final Map<String, ConfigurationKey> files = readFiles(rootNode);
 157  
 
 158  
       final PropertiesDefinitionContext context;
 159  0
       if (tlds == null)
 160  
       {
 161  0
         context =
 162  
             new PropertiesDefinitionContext(environments, nodes, groups, files);
 163  
       }
 164  
       else
 165  
       {
 166  0
         context =
 167  
             new PropertiesDefinitionContext(tlds, environments, nodes, groups,
 168  
                 files);
 169  
       }
 170  0
       return context;
 171  
     }
 172  0
     catch (final JDOMException e)
 173  
     {
 174  0
       throw new ConfigException(systemId, e);
 175  
     }
 176  0
     catch (final IOException e)
 177  
     {
 178  0
       throw new ConfigException(systemId, e);
 179  
     }
 180  
   }
 181  
 
 182  
   private Set<String> readSet(final Element rootNode, final String setGi,
 183  
       final String elementGi)
 184  
   {
 185  0
     return readSet(rootNode, setGi, elementGi, new HashSet<String>());
 186  
   }
 187  
 
 188  
   @SuppressWarnings("unchecked")
 189  
   private Set<String> readSet(final Element rootNode, final String setGi,
 190  
       final String elementGi, final Set<String> defaultSet)
 191  
   {
 192  0
     final Element set = rootNode.getChild(setGi, NS);
 193  0
     if (set != null)
 194  
     {
 195  0
       final Set<String> collection = new HashSet<String>();
 196  0
       final List<Element> elements = set.getChildren(elementGi, NS);
 197  0
       for (final Element element : elements)
 198  
       {
 199  0
         final String text = element.getTextNormalize();
 200  0
         collection.add(text);
 201  0
       }
 202  
 
 203  0
       return collection;
 204  
     }
 205  
 
 206  0
     return defaultSet;
 207  
   }
 208  
 
 209  
   @SuppressWarnings("unchecked")
 210  
   private Map<String, ConfigurationKey> readFiles(final Element rootNode)
 211  
   {
 212  0
     final Map<String, ConfigurationKey> keys =
 213  
         new HashMap<String, ConfigurationKey>();
 214  
 
 215  0
     final Element keySet = rootNode.getChild("key-set", NS);
 216  0
     if (keySet != null)
 217  
     {
 218  0
       final List<Element> elements = keySet.getChildren("key", NS);
 219  0
       for (final Element element : elements)
 220  
       {
 221  0
         final ConfigurationKey key = readKey(element);
 222  0
         final Element files = element.getChild("files", NS);
 223  0
         if (files != null)
 224  
         {
 225  0
           final List<Element> fileElements = files.getChildren("file", NS);
 226  0
           for (final Element file : fileElements)
 227  
           {
 228  0
             final String text = file.getTextNormalize();
 229  0
             keys.put(text, key);
 230  0
           }
 231  0
         }
 232  
         else
 233  
         {
 234  0
           keys.put(null, key);
 235  
         }
 236  0
       }
 237  
     }
 238  0
     return keys;
 239  
   }
 240  
 
 241  
   private ConfigurationKey readKey(final Element element)
 242  
     throws NullArgumentException
 243  
   {
 244  0
     final EnvironmentId environmentId = readEnvironment(element);
 245  0
     final ApplicationId applicationId = readApplication(element);
 246  0
     final ConfigurationKey key =
 247  
         new ConfigurationKey(environmentId, applicationId);
 248  0
     return key;
 249  
   }
 250  
 
 251  
   private EnvironmentId readEnvironment(final Element element)
 252  
   {
 253  0
     final Element environment = element.getChild("environment", NS);
 254  
 
 255  
     final EnvironmentId environmentId;
 256  0
     if (environment != null)
 257  
     {
 258  0
       final String name = norm(environment.getChildTextNormalize("name", NS));
 259  0
       final String node = norm(environment.getChildTextNormalize("node", NS));
 260  
 
 261  0
       environmentId = new EnvironmentId(name, node);
 262  0
     }
 263  
     else
 264  
     {
 265  0
       environmentId = EnvironmentId.ANY_ENV;
 266  
     }
 267  0
     return environmentId;
 268  
   }
 269  
 
 270  
   private ApplicationId readApplication(final Element element)
 271  
   {
 272  0
     final Element application = element.getChild("application", NS);
 273  
 
 274  
     final ApplicationId applicationId;
 275  0
     if (application != null)
 276  
     {
 277  0
       final String group = norm(application.getChildTextNormalize("group", NS));
 278  0
       final String artifact =
 279  
           norm(application.getChildTextNormalize("artifact", NS));
 280  0
       final String version =
 281  
           norm(application.getChildTextNormalize("version", NS));
 282  0
       applicationId = new ApplicationId(group, artifact, version);
 283  0
     }
 284  
     else
 285  
     {
 286  0
       applicationId = ApplicationId.ANY_APP;
 287  
     }
 288  0
     return applicationId;
 289  
   }
 290  
 
 291  
   private static String norm(final String text)
 292  
   {
 293  0
     if (StringUtils.isBlank(text))
 294  
     {
 295  0
       return null;
 296  
     }
 297  0
     return text;
 298  
   }
 299  
 }