blob: a13d5e79c364f77f6275878af1ebeb25264c707e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.deployment.rp.autoconf;
import java.io.File;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Utility class that injects dependencies. Can be used to unit test service implementations.
*/
public class Utils
{
/**
* Configures an object to use a null object for the specified service interface.
*
* @param object the object
* @param iface the service interface
*/
public static void configureObject(Object object, Class iface)
{
configureObject(object, iface, createNullObject(iface));
}
/**
* Creates a null object for a service interface.
*
* @param iface the service interface
* @return a null object
*/
public static <T> T createNullObject(Class<T> iface)
{
return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, new DefaultNullObject());
}
/**
* Wraps the given handler in an adapter that will try to pass on received invocations to the hander if that has
* an applicable methods else it defaults to a NullObject.
*
* @param iface the service interface
* @param handler the handler to pass invocations to.
* @return an adapter that will try to pass on received invocations to the given handler
*/
public static <T> T createMockObjectAdapter(Class<T> iface, final Object handler)
{
return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, new DefaultNullObject()
{
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
try
{
Method bridge = handler.getClass().getMethod(method.getName(), method.getParameterTypes());
bridge.setAccessible(true);
return bridge.invoke(handler, args);
}
catch (NoSuchMethodException ex)
{
return super.invoke(proxy, method, args);
}
catch (InvocationTargetException ex)
{
throw ex.getCause();
}
}
});
}
/**
* Configures an object to use a specific implementation for the specified service interface.
*
* @param object the object
* @param iface the service interface
* @param instance the implementation
*/
public static void configureObject(Object object, Class iface, Object instance)
{
Class serviceClazz = object.getClass();
while (serviceClazz != null)
{
Field[] fields = serviceClazz.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
for (int j = 0; j < fields.length; j++)
{
if (fields[j].getType().equals(iface))
{
try
{
// synchronized makes sure the field is actually written to immediately
synchronized (new Object())
{
fields[j].set(object, instance);
}
}
catch (Exception e)
{
throw new IllegalStateException("Could not set field " + fields[j].getName() + " on " + object);
}
}
}
serviceClazz = serviceClazz.getSuperclass();
}
}
/**
* Remove the given directory and all it's files and subdirectories
*
* @param directory the name of the directory to remove
*/
public static void removeDirectoryWithContent(File directory)
{
if ((directory == null) || !directory.exists())
{
return;
}
File[] filesAndSubDirs = directory.listFiles();
for (int i = 0; i < filesAndSubDirs.length; i++)
{
File file = filesAndSubDirs[i];
if (file.isDirectory())
{
removeDirectoryWithContent(file);
}
// else just remove the file
file.delete();
}
directory.delete();
}
}