X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=blobdiff_plain;f=org.argeo.api.app%2Fsrc%2Forg%2Fargeo%2Fapi%2Fapp%2FRankedObject.java;fp=org.argeo.api.app%2Fsrc%2Forg%2Fargeo%2Fapi%2Fapp%2FRankedObject.java;h=e9c47ce3b8d1d469cf9263d534879e0777ffb9b2;hp=0000000000000000000000000000000000000000;hb=ddc605514409368c46a8dadbbd914c4b1e61596a;hpb=db14c82991d4e17c45b2a5789dd94a6a839f5eaa diff --git a/org.argeo.api.app/src/org/argeo/api/app/RankedObject.java b/org.argeo.api.app/src/org/argeo/api/app/RankedObject.java new file mode 100644 index 0000000..e9c47ce --- /dev/null +++ b/org.argeo.api.app/src/org/argeo/api/app/RankedObject.java @@ -0,0 +1,113 @@ +package org.argeo.api.app; + +import java.util.Map; + +import org.argeo.api.cms.CmsLog; + +/** + * A container for an object whose relevance can be ranked. Typically used in an + * OSGi context with the service.ranking property. + */ +public class RankedObject { + private final static CmsLog log = CmsLog.getLog(RankedObject.class); + + private final static String SERVICE_RANKING = "service.ranking"; +// private final static String SERVICE_ID = "service.id"; + + private T object; + private Map properties; + private final int rank; + + public RankedObject(T object, Map properties) { + this(object, properties, extractRanking(properties)); + } + + public RankedObject(T object, Map properties, int rank) { + super(); + this.object = object; + this.properties = properties; + this.rank = rank; + } + + private static int extractRanking(Map properties) { + if (properties == null) + return 0; + if (properties.containsKey(SERVICE_RANKING)) + return (Integer) properties.get(SERVICE_RANKING); +// else if (properties.containsKey(SERVICE_ID)) +// return (Long) properties.get(SERVICE_ID); + else + return 0; + } + + public T get() { + return object; + } + + public Map getProperties() { + return properties; + } + + public int getRank() { + return rank; + } + + @Override + public int hashCode() { + return object.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof RankedObject)) + return false; + RankedObject other = (RankedObject) obj; + return rank == other.rank && object.equals(other.object); + } + + @Override + public String toString() { + return object.getClass().getName() + " with rank " + rank; + } + + public static boolean hasHigherRank(Map> map, K key, Map properties) { + if (!map.containsKey(key)) + return true; + RankedObject rankedObject = new RankedObject<>(null, properties); + RankedObject current = map.get(key); + return current.getRank() < rankedObject.getRank(); + } + + /** + * @return the {@link RankedObject}, or null if the current one was + * kept + */ + public static RankedObject putIfHigherRank(Map> map, K key, T object, + Map properties) { + RankedObject rankedObject = new RankedObject<>(object, properties); + if (!map.containsKey(key)) { + map.put(key, rankedObject); + if (log.isTraceEnabled()) + log.trace( + "Added " + key + " as " + object.getClass().getName() + " with rank " + rankedObject.getRank()); + return rankedObject; + } else { + RankedObject current = map.get(key); + if (current.getRank() < rankedObject.getRank()) { + map.put(key, rankedObject); + if (log.isDebugEnabled()) + log.debug("Replaced " + key + " by " + object.getClass().getName() + " with rank " + + rankedObject.getRank()); + return rankedObject; + } else if (current.getRank() == rankedObject.getRank()) { + log.error("Already " + key + " by " + current.get().getClass().getName() + " with rank " + + rankedObject.getRank() + ", ignoring " + rankedObject.get().getClass().getName()); + return null; + } else { + return null; + } + } + + } + +}