jadex.bridge.nonfunctional.search.ComposedEvaluator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-platform-bridge Show documentation
Show all versions of jadex-platform-bridge Show documentation
Jadex bridge is a base package for kernels and platforms, i.e., it is used by both and provides commonly used interfaces and classes for active components and their management.
package jadex.bridge.nonfunctional.search;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jadex.bridge.service.IService;
import jadex.commons.Tuple2;
import jadex.commons.future.CollectionResultListener;
import jadex.commons.future.CounterResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.commons.future.IResultListener;
/**
* Evaluator composed of multiple weighted evaluators.
*/
public class ComposedEvaluator implements IServiceEvaluator, IServiceRanker
{
/** The evaluators. */
protected List> evaluators;
/**
* Creates the combiner.
*/
public ComposedEvaluator()
{
evaluators = new ArrayList>();
}
/**
* Adds a new evaluator with a weight of 1.0.
*
* @param evaluator The new evaluator.
*/
public void addEvaluator(IServiceEvaluator evaluator)
{
addEvaluator(evaluator, 1.0);
}
/**
* Adds a new evaluator.
*
* @param evaluator The new evaluator.
* @param weight The weight of the evaluator relative to other evaluators.
*/
public void addEvaluator(IServiceEvaluator evaluator, double weight)
{
evaluators.add(new Tuple2(evaluator, weight));
}
/**
* Removes an evaluator.
*
* @param evaluator The evaluator.
*/
public void removeEvaluator(IServiceEvaluator evaluator)
{
for (int i = 0; i < evaluators.size(); ++i)
{
if (evaluators.get(i).getFirstEntity().equals(evaluator))
{
evaluators.remove(i);
break;
}
}
}
/**
* Evaluates the service in detail. This method
* must return an evaluation of the service in
* the range between 0 (worst/unacceptable) to
* 1 (best/preferred).
*
* @param service The service being evaluated.
*
* @return An evaluation of the service in a
* range between 0 and 1 (inclusive).
*/
public IFuture evaluate(IService service)
{
final Future ret = new Future();
// double ret = 0;
double tw = 0;
for (Tuple2 eval : evaluators)
{
tw += eval.getSecondEntity();
}
final double totalweight = tw;
final CollectionResultListener crl = new CollectionResultListener(evaluators.size(), false, new IResultListener>()
{
public void resultAvailable(Collection result)
{
double res = 0;
for (Double sres : result)
{
res += sres;
}
res /= totalweight;
ret.setResult(res);
}
public void exceptionOccurred(Exception exception)
{
ret.setException(exception);
}
});
for(Tuple2 eval : evaluators)
{
final double weight = eval.getSecondEntity();
eval.getFirstEntity().evaluate(service).addResultListener(new IResultListener()
{
public void resultAvailable(Double result)
{
crl.resultAvailable(result * weight);
}
public void exceptionOccurred(Exception exception)
{
crl.exceptionOccurred(exception);
}
});
}
return ret;
}
/**
* Ranks services according to non-functional criteria.
*
* @param unrankedservices Unranked list of services.
* @return Ranked list of services.
*/
public IFuture> rank(final List unrankedservices)
{
final Future> ret = new Future>();
final Map evalmap = Collections.synchronizedMap(new HashMap());
final CounterResultListener crl = new CounterResultListener(unrankedservices.size(), new IResultListener()
{
public void resultAvailable(Void result)
{
Collections.sort(unrankedservices, new Comparator()
{
public int compare(S s1, S s2)
{
return (int)-Math.signum(evalmap.get(s1) - evalmap.get(s2));
}
});
ret.setResult(unrankedservices);
}
public void exceptionOccurred(Exception exception)
{
ret.setException(exception);
}
});
for(int i = 0; i < unrankedservices.size(); ++i)
{
final IService service = (IService) unrankedservices.get(i);
evaluate(service).addResultListener(new IResultListener()
{
public void resultAvailable(Double result)
{
evalmap.put(service, result);
crl.resultAvailable(null);
}
public void exceptionOccurred(Exception exception)
{
crl.exceptionOccurred(exception);
}
});
}
return ret;
}
/**
* Ranks services according to non-functional criteria.
*
* @param unrankedservices Unranked list of services.
* @return Ranked list of services and scores.
*/
public IFuture>> rankWithScores(final List unrankedservices)
{
final Future>> ret = new Future>>();
final Map evalmap = Collections.synchronizedMap(new HashMap());
final CounterResultListener crl = new CounterResultListener(unrankedservices.size(), new IResultListener()
{
public void resultAvailable(Void result)
{
Collections.sort(unrankedservices, new Comparator()
{
public int compare(S s1, S s2)
{
return (int)-Math.signum(evalmap.get(s1) - evalmap.get(s2));
}
});
List> evas = new ArrayList>();
for(S ser: unrankedservices)
{
evas.add(new Tuple2(ser, evalmap.get(ser)));
}
ret.setResult(evas);
}
public void exceptionOccurred(Exception exception)
{
ret.setException(exception);
}
});
for(int i = 0; i < unrankedservices.size(); ++i)
{
final IService service = (IService) unrankedservices.get(i);
evaluate(service).addResultListener(new IResultListener()
{
public void resultAvailable(Double result)
{
evalmap.put(service, result);
crl.resultAvailable(null);
}
public void exceptionOccurred(Exception exception)
{
crl.exceptionOccurred(exception);
}
});
}
return ret;
}
}