Coverage Report - org.mule.module.launcher.DefaultAppBloodhound
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultAppBloodhound
0%
0/45
0%
0/20
0
DefaultAppBloodhound$1
0%
0/10
0%
0/10
0
 
 1  
 /*
 2  
  * $Id: DefaultAppBloodhound.java 20792 2010-12-16 16:58:49Z aperepel $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.module.launcher;
 12  
 
 13  
 import org.mule.api.MuleRuntimeException;
 14  
 import org.mule.config.i18n.MessageFactory;
 15  
 import org.mule.module.launcher.descriptor.ApplicationDescriptor;
 16  
 import org.mule.module.launcher.descriptor.DescriptorParser;
 17  
 import org.mule.module.launcher.descriptor.EmptyApplicationDescriptor;
 18  
 import org.mule.module.launcher.descriptor.Preferred;
 19  
 import org.mule.module.launcher.descriptor.PropertiesDescriptorParser;
 20  
 import org.mule.module.reboot.MuleContainerBootstrapUtils;
 21  
 import org.mule.util.FileUtils;
 22  
 import org.mule.util.FilenameUtils;
 23  
 import org.mule.util.PropertiesUtils;
 24  
 
 25  
 import java.io.File;
 26  
 import java.io.IOException;
 27  
 import java.util.ArrayList;
 28  
 import java.util.Collection;
 29  
 import java.util.Collections;
 30  
 import java.util.Comparator;
 31  
 import java.util.HashMap;
 32  
 import java.util.Iterator;
 33  
 import java.util.Map;
 34  
 import java.util.Properties;
 35  
 
 36  
 import javax.imageio.spi.ServiceRegistry;
 37  
 
 38  
 import org.apache.commons.collections.MultiMap;
 39  
 import org.apache.commons.collections.map.MultiValueMap;
 40  
 import org.apache.commons.io.filefilter.WildcardFileFilter;
 41  
 
 42  
 /**
 43  
  *
 44  
  */
 45  
 public class DefaultAppBloodhound implements AppBloodhound
 46  
 {
 47  
 
 48  
     // file extension -> parser implementation
 49  0
     protected Map<String, DescriptorParser> parserRegistry = new HashMap<String, DescriptorParser>();
 50  
 
 51  
     public DefaultAppBloodhound()
 52  0
     {
 53  
         // defaults first
 54  0
         parserRegistry.put("properties", new PropertiesDescriptorParser());
 55  
 
 56  0
         final Iterator<DescriptorParser> it = ServiceRegistry.lookupProviders(DescriptorParser.class);
 57  
 
 58  0
         MultiMap overrides = new MultiValueMap();
 59  0
         while (it.hasNext())
 60  
         {
 61  0
             final DescriptorParser parser = it.next();
 62  0
             overrides.put(parser.getSupportedFormat(), parser);
 63  0
         }
 64  0
         mergeParserOverrides(overrides);
 65  0
     }
 66  
 
 67  
     public ApplicationDescriptor fetch(String appName) throws IOException
 68  
     {
 69  0
         final File appsDir = MuleContainerBootstrapUtils.getMuleAppsDir();
 70  0
         File appDir = new File(appsDir, appName);
 71  0
         if (!appDir.exists())
 72  
         {
 73  0
             throw new MuleRuntimeException(
 74  
                     MessageFactory.createStaticMessage(
 75  
                             String.format("Application directory does not exist: '%s'", appDir)));
 76  
         }
 77  
         // list mule-deploy.* files
 78  
         @SuppressWarnings("unchecked")
 79  0
         Collection<File> deployFiles = FileUtils.listFiles(appDir, new WildcardFileFilter("mule-deploy.*"), null);
 80  0
         if (deployFiles.size() > 1)
 81  
         {
 82  
             // TODO need some kind of an InvalidAppFormatException
 83  0
             throw new MuleRuntimeException(
 84  
                     MessageFactory.createStaticMessage(
 85  
                             String.format("More than one mule-deploy descriptors found in application '%s'", appName)));
 86  
         }
 87  
 
 88  
         ApplicationDescriptor desc;
 89  
 
 90  
         // none found, return defaults
 91  0
         if (deployFiles.isEmpty())
 92  
         {
 93  0
             desc = new EmptyApplicationDescriptor(appName);
 94  
         }
 95  
         else
 96  
         {
 97  
             // lookup the implementation by extension
 98  0
             final File descriptorFile = deployFiles.iterator().next();
 99  0
             final String ext = FilenameUtils.getExtension(descriptorFile.getName());
 100  0
             final DescriptorParser descriptorParser = parserRegistry.get(ext);
 101  
 
 102  0
             if (descriptorParser == null)
 103  
             {
 104  
                 // TODO need some kind of an InvalidAppFormatException
 105  0
                 throw new MuleRuntimeException(
 106  
                         MessageFactory.createStaticMessage(
 107  
                                 String.format("Unsupported deployment descriptor format for app '%s': %s", appName, ext)));
 108  
             }
 109  
 
 110  0
             desc = descriptorParser.parse(descriptorFile);
 111  
             // app name is external to the deployment descriptor
 112  0
             desc.setAppName(appName);
 113  
         }
 114  
 
 115  
         // get a ref to an optional app props file (right next to the descriptor)
 116  0
         final File appPropsFile = new File(appDir, ApplicationDescriptor.DEFAULT_APP_PROPERTIES_RESOURCE);
 117  0
         if (appPropsFile.exists() && appPropsFile.canRead())
 118  
         {
 119  0
             final Properties props = PropertiesUtils.loadProperties(appPropsFile.toURI().toURL());
 120  
             // ugh, no straightforward way to convert to a map
 121  0
             Map<String, String> m = new HashMap<String, String>(props.size());
 122  0
             for (Object key : props.keySet())
 123  
             {
 124  0
                 m.put(key.toString(), props.getProperty(key.toString()));
 125  
             }
 126  0
             desc.setAppProperties(m);
 127  
         }
 128  
 
 129  0
         return desc;
 130  
 
 131  
     }
 132  
 
 133  
     /**
 134  
      * Merge default and discovered overrides for descriptor parsers, taking weight into account
 135  
      *
 136  
      * @param overrides discovered parser overrides
 137  
      */
 138  
     protected void mergeParserOverrides(MultiMap overrides)
 139  
     {
 140  
         // for each key in default parser registry
 141  0
         for (Map.Entry<String, DescriptorParser> entry : parserRegistry.entrySet())
 142  
         {
 143  
             @SuppressWarnings("unchecked")
 144  0
             final Collection<DescriptorParser> candidates = (Collection<DescriptorParser>) overrides.get(entry.getKey());
 145  
 
 146  0
             if (candidates == null)
 147  
             {
 148  0
                 continue;
 149  
             }
 150  
             // if any override candidates found, sort by weight reverse
 151  0
             final ArrayList<DescriptorParser> sorted = new ArrayList<DescriptorParser>(candidates);
 152  0
             final Comparator<DescriptorParser> annotationComparator = new Comparator<DescriptorParser>()
 153  0
             {
 154  
                 public int compare(DescriptorParser p1, DescriptorParser p2)
 155  
                 {
 156  0
                     final Preferred ann1 = p1.getClass().getAnnotation(Preferred.class);
 157  0
                     final Preferred ann2 = p2.getClass().getAnnotation(Preferred.class);
 158  
 
 159  0
                     if (ann1 == null && ann2 == null)
 160  
                     {
 161  0
                         return 0;
 162  
                     }
 163  
 
 164  0
                     if (ann1 != null && ann2 == null)
 165  
                     {
 166  0
                         return 1;
 167  
                     }
 168  
 
 169  0
                     if (ann1 == null)
 170  
                     {
 171  0
                         return -1;
 172  
                     }
 173  
 
 174  
                     // else compare annotation weights
 175  0
                     return new Integer(ann1.weight()).compareTo(ann2.weight());
 176  
                 }
 177  
             };
 178  0
             Collections.sort(sorted, Collections.reverseOrder(annotationComparator));
 179  
 
 180  
             // put the top one in the registry
 181  0
             parserRegistry.put(entry.getKey(), sorted.get(0));
 182  0
         }
 183  
 
 184  0
     }
 185  
 }