/**
 * Copyright (c) 2010 RedEngine Ltd, http://www.redengine.co.nz. All rights reserved.
 *
 * This program is licensed to you under the Apache License Version 2.0,
 * and you may not use this file except in compliance with the Apache License Version 2.0.
 * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Apache License Version 2.0 is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
 */
package net.stickycode.mockwire.configured;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import net.stickycode.configured.ConfigurationSource;
import net.stickycode.mockwire.ClasspathResourceNotFoundException;


public class MockwireConfigurationSource
    implements ConfigurationSource {

  private Map<String, String> configuration = new HashMap<String, String>();

  @Override
  public boolean hasValue(String key) {
    return configuration.containsKey(key);
  }

  @Override
  public String getValue(String key) {
    return configuration.get(key);
  }

  public void add(Class<?> testClass, String s) {
    int index = s.indexOf('=');
    if (index > -1)
      addValue(s.substring(0, index), s.substring(index + 1));
    else
      loadClasspathResource(resolveBaseClass(testClass), s);
  }

  private Class<?> resolveBaseClass(Class<?> testClass) {
    if (testClass.isMemberClass())
      return testClass.getDeclaringClass();

    return testClass;
  }

  void loadClasspathResource(Class<?> testClass, String resource) {
    InputStream i = testClass.getResourceAsStream(resource);
    if (i == null)
      throw new ClasspathResourceNotFoundException(resource);

    Properties p = new Properties();
    try {
      p.load(i);
      i.close();
    }
    catch (IOException e) {
      throw new ClasspathResourceNotFoundException(e, resource);
    }

    for (String name : p.stringPropertyNames()) {
      addValue(name, p.getProperty(name));
    }
  }

  private void addValue(String key, String value) {
    configuration.put(key, value);
  }

  public void add(Class<?> testClass, String[] value) {
    for (String s : value) {
      add(testClass, s);
    }

  }

}

@@ -892,16 +892,74 @@
 rties;%0A%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A
 import n
@@ -1152,16 +1152,77 @@
 urce %7B%0A%0A
+  private Logger log = LoggerFactory.getLogger(getClass());%0A%0A
   privat
@@ -1474,32 +1474,153 @@
 .get(key);%0A  %7D%0A%0A
+  public void add(Class%3C?%3E testClass, String%5B%5D value) %7B%0A    for (String s : value) %7B%0A      add(testClass, s);%0A    %7D%0A  %7D%0A%0A
   public void ad
@@ -2100,133 +2100,597 @@
 i = 
-testClass.getResourceAsStream(resource);%0A    if (i == null)%0A      throw new ClasspathResourceNotFoundException(resource);%0A%0A  
+getResourceStream(testClass, resource);%0A    Properties p;%0A%0A    try %7B%0A      p = loadProperties(resource, i);%0A    %7D%0A    finally %7B%0A      closeStream(i, testClass, resource);%0A    %7D%0A%0A    for (String name : p.stringPropertyNames()) %7B%0A      addValue(name, p.getProperty(name));%0A    %7D%0A  %7D%0A%0A  void closeStream(InputStream i, Class%3C?%3E testClass, String resource) %7B%0A    try %7B%0A      i.close();%0A    %7D%0A    catch (IOException e) %7B%0A      log.warn(%22Failed to close input stream of %7B%7D on %7B%7D. Assuming thats not a critical failure and ignoring.%22, new Object%5B%5D %7Bresource, testClass.getName(), e%7D);%0A    %7D%0A  %7D%0A%0A
   Pr
@@ -2702,16 +2702,12 @@
 ies 
-p = new 
+load
 Prop
@@ -2717,20 +2717,90 @@
 ies(
-);%0A    try %7B
+String resource, InputStream i) %7B%0A    try %7B%0A      Properties p = new Properties();
 %0A   
@@ -2815,33 +2815,32 @@
 d(i);%0A      
-i.close()
+return p
 ;%0A    %7D%0A    
@@ -2938,325 +2938,344 @@
   %7D%0A
-%0A    for (String name : p.stringPropertyNames()) %7B%0A      addValue(name, p.getProperty(name));%0A    %7D%0A  %7D%0A%0A  private void addValue(String key, String value) %7B%0A    configuration.put(key, value);%0A  %7D%0A%0A  public void add(Class%3C?%3E testClass, String%5B%5D value) %7B%0A    for (String s : value) %7B%0A      add(testClass, s);%0A    %7D%0A%0A  %7D
+  %7D%0A%0A  private InputStream getResourceStream(Class%3C?%3E testClass, String resource) %7B%0A    InputStream i = testClass.getResourceAsStream(resource);%0A    if (i == null)%0A      throw new ClasspathResourceNotFoundException(resource);%0A    return i;%0A  %7D%0A%0A  private void addValue(String key, String value) %7B%0A    configuration.put(key, value);%0A  %7D%0A
 %0A%0A%7D%0A

Improve the error handling, including excepting and logging appropriately