public class Claimed extends AbstractMessage<ASIMOVMessageID> implements Serializable, JSONConvertible<Claimed> { /** */ private static final long serialVersionUID = 1L; private static final Logger LOG = LogUtil.getLogger(Claimed.class); public boolean available; private ASIMOVMessageID replyToId; protected Claimed() { // zero argument constructor } public Claimed( final Claim source, final SimTime time, final AgentID senderID, final AgentID receiverID) { super(source.getID(), senderID.getModelID(), senderID, receiverID); replyToId = source.getID(); } /** @return the available */ public boolean isAvailable() { return available; } /** @param available the available to set */ public void setAvailable(boolean available) { this.available = available; } /** @return the id */ public ASIMOVMessageID getReplyToId() { return replyToId; } /** @see Identifier#toString() */ @Override public String toString() { return String.format("%s%s", getClass().getSimpleName(), toJSON()); } /** @see JSONConvertible#toJSON() */ @Override public String toJSON() { try { // final JsonNode node = JsonUtil.getJOM().valueToTree(this); return JsonUtil.getJOM().writeValueAsString(this); } catch (final JsonProcessingException e) { LOG.warn("Problem marshalling " + getClass().getName() + " to JSON", e); return String.format("id=\"%s\"", getID()); } } @Override public Claimed fromJSON(final String jsonValue) { return JsonUtil.fromJSONString(jsonValue, Claimed.class); } }
/** {@link JadeTest} */ public class JadeTest { /** */ private static final Logger LOG = LogUtil.getLogger(JadeTest.class); /** * from: Luis Lezcano Airaldi <*****@*****.**> to: [email protected] date: Sat, * Jun 7, 2014 at 3:10 PM * * <p>Hello! It's very easy to use Jade as a library. Here's an example from a small application I * made: */ public void testJade1() { // This is the important method. This launches the jade platform. final Runtime rt = Runtime.instance(); final Profile profile = new ProfileImpl(); // With the Profile you can set some options for the container profile.setParameter(Profile.PLATFORM_ID, "Platform Name"); profile.setParameter(Profile.CONTAINER_NAME, "Container Name"); // Create the Main Container final AgentContainer mainContainer = rt.createMainContainer(profile); final String agentName = "manager"; final String agentType = "ia.main.AgentManager"; // FIXME final Object[] agentArgs = {}; try { // Here I create an agent in the main container and start it. final AgentController ac = mainContainer.createNewAgent(agentName, agentType, agentArgs); ac.start(); } catch (final StaleProxyException e) { LOG.error( String.format( "Problem creating/starting Jade agent '%s'" + " of type: %s with args: %s", agentName, agentType, Arrays.asList(agentArgs)), e); } } }
/** * {@link WeightedProduct} implements a {@link MultiCriteriaDecisionAnalyzer} that compares {@link * MultiCriteriaWeightedAlternative} s by the product of each criterion's weight with the policy's * respective {@link #getNormalizedWeights()} (see <a * href="https://www.wikiwand.com/en/Weighted_product_model">the method by Bridgman (1922) and * Miller & Starr (1969)</a>) * * @param <C> * @version $Id: 06fdeb50ce15c9a8366dc2eb3c9c54e11a324794 $ * @author Rick van Krevelen */ class WeightedProduct<A extends MultiCriteriaWeightedAlternative<C>, C> implements MultiCriteriaDecisionAnalyzer<A, C> { /** */ private static final Logger LOG = LogUtil.getLogger(WeightedProduct.class); /** */ private final Map<C, Number> weights; /** */ private final Map<C, Double> normalizedWeights = new HashMap<>(); /** */ public WeightedProduct() { this(null); } /** */ public WeightedProduct(final Map<C, Number> weights) { this.weights = weights; } @Override public Map<C, Number> getWeights() { return this.weights; } // @Override public Map<C, Double> getNormalizedWeights() { return this.normalizedWeights; } public void normalize() { double total = 0.0d; for (Number weight : getWeights().values()) total += Math.abs(weight.doubleValue()); getNormalizedWeights().clear(); for (Map.Entry<C, Number> entry : getWeights().entrySet()) getNormalizedWeights() .put( entry.getKey(), total == 0.0 ? 1.0d / getWeights().size() : entry.getValue().doubleValue() / total); LOG.trace( "Normalized the criteria weights: " + getWeights() + " to: " + getNormalizedWeights()); } @Override public String toString() { return String.format( "%s[ weights: %s, normalized: %s ]", getClass().getSimpleName(), getWeights(), getNormalizedWeights()); } @Override public int compare(final A o1, final A o2) { double weightedProduct = 1.0d; for (Map.Entry<C, Double> entry : getNormalizedWeights().entrySet()) try { final C criterion = entry.getKey(); final double value1 = o1.evaluate(criterion).doubleValue(); final double value2 = o2.evaluate(criterion).doubleValue(); final double weight = entry.getValue().doubleValue(); final double factor = value1 == 0.0d || value2 == 0.0d ? 1.0d : Math.pow(value1 / value2, weight); LOG.trace( String.format( "%s factor: ( %.3f / %.3f ) ^ %.3f = %.3f", criterion, value1, value2, weight, factor)); weightedProduct *= factor; } catch (final Throwable e) { LOG.error("Problem comparing {} with {}", o1, o2, e); } final int result = Double.compare(weightedProduct, 1.0d); LOG.trace("Comparing {} with {}: {} >>> {}", o1, o2, weightedProduct, result); return result; } @Override public <K extends A, V> NavigableMap<K, V> apply(final Map<K, V> alternatives) { normalize(); final NavigableMap<K, V> result = new ConcurrentSkipListMap<K, V>(this); result.putAll(alternatives); return result; } @Override public <E extends A> NavigableSet<E> apply(final Collection<E> alternatives) { normalize(); final NavigableSet<E> result = new ConcurrentSkipListSet<E>(this); result.addAll(alternatives); return result; } }
/** * {@link StageUtil} utility class for interception and extension of an injected object's life cycle * * @version $Id: 1ee12291a4f37aa3235547ac54195dc1d0e9bdaa $ * @author Rick van Krevelen */ public class StageUtil implements Util { /** */ private static final Logger LOG = LogUtil.getLogger(StageUtil.class); /** */ private static final Map<Class<?>, Map<StageEvent, SortedMap<Method, Staged>>> stageEventHandlerCache = new HashMap<>(); /** */ private static final Map<Class<?>, Map<String, SortedMap<Method, Staged>>> customStageHandlerCache = new HashMap<>(); /** */ private static final Map<Class<?>, Set<Class<? extends Throwable>>> absorptionLevelCache = new HashMap<>(); /** {@link StageUtil} singleton constructor */ private StageUtil() { // utility class should not provide protected/public instances } /** decide which stage event handler to execute first */ private static final Comparator<Method> METHOD_COMPARATOR = new Comparator<Method>() { @Override public int compare(final Method o1, final Method o2) { if (o1 == o2) return 0; // compare priority int result = Integer.compare( o1.getAnnotation(Staged.class).priority(), o2.getAnnotation(Staged.class).priority()); if (result != 0) return result; // same priority; compare class hierarchy /* * result = o1.getDeclaringClass().getName() * .compareTo(o2.getDeclaringClass().getName()); if (result != 0) return result; */ // same priority and class; compare method name result = o1.getName().compareTo(o2.getName()); if (result != 0) return result; // same priority, class, and name; compare method name return toSignatureString(o1).compareTo(toSignatureString(o2)); } }; /** @param type */ private static synchronized void findHandlers(final Class<?> type) { LOG.trace("Caching handlers for " + type.getName()); final Map<StageEvent, SortedMap<Method, Staged>> handlersByEvent = type.getSuperclass() == Object.class || type.getSuperclass() == null ? new EnumMap<StageEvent, SortedMap<Method, Staged>>(StageEvent.class) : findEventHandlers(type.getSuperclass()); stageEventHandlerCache.put(type, handlersByEvent); final Map<String, SortedMap<Method, Staged>> handlersByStage = type.getSuperclass() == Object.class || type.getSuperclass() == null ? new HashMap<String, SortedMap<Method, Staged>>() : findStageHandlers(type.getSuperclass()); customStageHandlerCache.put(type, handlersByStage); for (Class<?> iface : type.getInterfaces()) { handlersByEvent.putAll(findEventHandlers(iface)); handlersByStage.putAll(findStageHandlers(iface)); } for (Method method : type.getDeclaredMethods()) { final Staged ann = method.getAnnotation(Staged.class); if (ann == null) continue; for (StageEvent on : ann.on()) { SortedMap<Method, Staged> handlers = handlersByEvent.get(on); if (handlers == null) { handlers = new TreeMap<>(METHOD_COMPARATOR); handlersByEvent.put(on, handlers); } handlers.put(method, ann); } for (String stage : ann.onCustom()) { SortedMap<Method, Staged> handlers = handlersByStage.get(stage); if (handlers == null) { handlers = new TreeMap<>(METHOD_COMPARATOR); handlersByStage.put(stage, handlers); } handlers.put(method, ann); } } // if (handlersByEvent.isEmpty() && handlersByStage.isEmpty()) // LOG.warn("No @" + Staged.class.getSimpleName() // + " annotations found in target: " + type.getName()); } /** * @param type * @param event * @return */ public static synchronized Map<StageEvent, SortedMap<Method, Staged>> findEventHandlers( final Class<?> type) { Map<StageEvent, SortedMap<Method, Staged>> result = stageEventHandlerCache.get(type); if (result == null) { findHandlers(type); result = stageEventHandlerCache.get(type); } return result; } /** * @param type * @param event * @return */ public static Map<Method, Staged> findEventHandlers(final Class<?> type, final StageEvent event) { final Map<Method, Staged> result = findEventHandlers(type).get(event); if (result == null) return Collections.emptyMap(); return result; } /** * @param type * @param stage * @return */ public static synchronized Map<String, SortedMap<Method, Staged>> findStageHandlers( final Class<?> type) { Map<String, SortedMap<Method, Staged>> result = customStageHandlerCache.get(type); if (result == null) { findHandlers(type); result = customStageHandlerCache.get(type); } return result; } /** * @param type * @param stage * @return */ public static Map<Method, Staged> findStageHandlers(final Class<?> type, final String stage) { final Map<Method, Staged> result = findStageHandlers(type).get(stage); if (result == null) return Collections.emptyMap(); return result; } /** * @param type * @return */ public static synchronized SortedSet<String> findStages( final Class<?> type, final InjectStaged.StageSelector selector) { LOG.trace("Caching " + selector + " stages for " + type.getName()); SortedSet<String> result = selector.getCache().get(type); if (result != null) return result; result = new TreeSet<>(); selector.getCache().put(type, result); InjectStaged staging = type.getAnnotation(InjectStaged.class); if (staging != null) for (String stage : selector.selectStages(staging)) result.add(stage); for (Class<?> iface : type.getInterfaces()) result.addAll(findStages(iface, selector)); if (type.getSuperclass() != Object.class && type.getSuperclass() != null) result.addAll(findStages(type.getSuperclass(), selector)); return result; } /** * use sub-most available specification (if any) from Objects only (ignore interfaces and possibly * overridden specifications) * * @param type * @return */ public static synchronized Set<Class<? extends Throwable>> findAbsorptionLevels( final Class<?> type) { LOG.trace("Caching absorption levels for " + type.getName()); Set<Class<? extends Throwable>> result = absorptionLevelCache.get(type); if (result != null) return result; absorptionLevelCache.put(type, result); Class<?> stagingType = type; InjectStaged staging = stagingType.getAnnotation(InjectStaged.class); while (staging == null && stagingType.getSuperclass() != Object.class) { stagingType = stagingType.getSuperclass(); staging = stagingType.getAnnotation(InjectStaged.class); } if (staging != null) result = subsume(type.getName(), staging.ignore()); // else // LOG.warn("(Super)type missing @" // + InjectStaged.class.getSimpleName() + ": " // + type.getName()); return result; } /** * @param type * @return */ public static Set<Class<? extends Throwable>> findAbsorptionLevels( final Class<?> type, final Method method) { final Set<Class<? extends Throwable>> result; final Staged staged = method.getAnnotation(Staged.class); // override class-level annotation by method-level annotation if (staged == null) result = findAbsorptionLevels(type); else result = subsume(toSignatureString(method), staged.ignore()); LOG.trace("Absorption for " + toSignatureString(method) + ": " + result); return result; } /** * @param source the (annotation) origin * @param ignore the set of {@link Throwable}s to reduce (if subsumed) * @return */ @SafeVarargs public static Set<Class<? extends Throwable>> subsume( final String source, final Class<? extends Throwable>... ignore) { final Set<Class<? extends Throwable>> result = new HashSet<>(); if (ignore != null && ignore.length != 0) outer: for (Class<? extends Throwable> cls : ignore) { for (Class<? extends Throwable> old : result) { if (old.isAssignableFrom(cls)) { LOG.info( "ignore() level '" + old.getName() + "' subsumes '" + cls.getName() + "' annotated in " + source); continue outer; } if (cls.isAssignableFrom(old)) { LOG.info( "ignore() level '" + cls.getName() + "' annotated in " + source + " subsumes '" + old.getName() + "'"); result.remove(old); } } result.add(cls); } return result; } /** * shortcut/convenience method * * @param provider * @return * @throws Throwable */ public static <T> T inject(final Provider<T> provider) throws Throwable { return inject(provider, null); } /** * @param provider * @param stageObserver * @return * @throws Throwable */ public static <T> T inject(final Provider<T> provider, final Observer<StageChange> stageObserver) throws Throwable { @SuppressWarnings("unchecked") final Class<T> type = (Class<T>) ClassUtil.getTypeArguments(Provider.class, provider.getClass()).get(0); boolean success = true; if (stageObserver != null) stageObserver.onNext(new StageChangeImpl(type, null, Stage.PREPARING, null)); success &= invokeEventHandlers(stageObserver, type, null, null, StageEvent.BEFORE_PROVIDE); success &= invokeStages( stageObserver, type, null, findStages(type, InjectStaged.BEFORE_PROVIDE_SELECTOR)); if (stageObserver != null) stageObserver.onNext(new StageChangeImpl(type, null, Stage.PROVIDING, null)); final FinalizeDecorator<T> subject = FinalizeDecorator.from(stageObserver, type, provider.get()); if (stageObserver != null) stageObserver.onNext(new StageChangeImpl(type, subject.getTarget(), Stage.PROVIDED, null)); success &= invokeEventHandlers( stageObserver, type, subject.getTarget(), null, StageEvent.AFTER_PROVIDE); success &= invokeStages( stageObserver, type, subject.getTarget(), findStages(type, InjectStaged.AFTER_PROVIDE_SELECTOR)); if (stageObserver != null && success) stageObserver.onNext(new StageChangeImpl(type, subject.getTarget(), Stage.STOPPED, null)); return subject.getTarget(); } public static <T> boolean invokeStages( final Observer<StageChange> stageObserver, final Class<T> type, final T target, final Collection<String> stages) throws Throwable { if (stages == null || stages.isEmpty()) return true; boolean success = true; for (String stage : stages) { if (stageObserver != null) stageObserver.onNext(new StageChangeImpl(type, target, Stage.STARTING, stage)); success &= invokeEventHandlers(stageObserver, type, target, stage, StageEvent.BEFORE_STAGE); if (stageObserver != null) stageObserver.onNext(new StageChangeImpl(type, target, Stage.STARTED, stage)); final List<String> nextStages = invokeStageHandlers(stageObserver, type, target, stage); success &= nextStages != null; if (stageObserver != null) stageObserver.onNext(new StageChangeImpl(type, target, Stage.STOPPING, stage)); success &= invokeEventHandlers(stageObserver, type, target, stage, StageEvent.AFTER_STAGE); if (nextStages != null && !nextStages.isEmpty()) { LOG.trace("Starting *nested* stage: " + nextStages); invokeStages(stageObserver, type, target, nextStages); } } return success; } public static <T> boolean invokeEventHandlers( final Observer<StageChange> stageObserver, final Class<T> type, final T target, final String currentStage, final StageEvent event) throws Throwable { Object result; boolean failed = false; for (Map.Entry<Method, Staged> entry : findEventHandlers(type, event).entrySet()) { LOG.trace( "Calling 'on=" + event.name() + "' handler method: " + toSignatureString(entry.getKey())); result = invoke(stageObserver, currentStage, type, target, entry.getKey()); failed |= result instanceof Throwable; } return !failed; } /** * @param stageObserver * @param type * @param target * @param currentStage * @return the next stage, or {@code null} if failed * @throws Throwable */ public static <T> List<String> invokeStageHandlers( final Observer<StageChange> stageObserver, final Class<T> type, final T target, final String currentStage) throws Throwable { Object result; boolean failed = false; final List<String> nextStages = new ArrayList<>(); for (Map.Entry<Method, Staged> entry : findStageHandlers(type, currentStage).entrySet()) { LOG.trace( "Calling 'onCustom=" + currentStage + "' handler method: " + toSignatureString(entry.getKey())); result = invoke(stageObserver, currentStage, type, target, entry.getKey()); if (result instanceof Throwable) failed = true; else if (entry.getValue().returnsNextStage()) { final String nextStage = result == null ? null : result.toString(); if (nextStage == null) LOG.error( "Illegal (void or null) next stage returned by " + toSignatureString(entry.getKey())); else nextStages.add(nextStage); } failed |= result instanceof Throwable; } return failed ? null : nextStages; } /** * @param stageObserver * @param type * @param currentStage * @param method * @param target * @param args * @return * @throws Throwable */ public static <T> Object invoke( final Observer<StageChange> stageObserver, final String currentStage, final Class<T> type, final T target, final Method method, final Object... args) throws Throwable { try { return method.invoke(target, args); } catch (Throwable t) { if (stageObserver != null) stageObserver.onNext( new StageChangeImpl(target.getClass(), target, Stage.FAILING, currentStage)); if (t instanceof InvocationTargetException) t = t.getCause(); for (Map.Entry<Method, Staged> entry : findEventHandlers(type, StageEvent.BEFORE_FAIL).entrySet()) { if (target == null && !Modifier.isStatic(entry.getKey().getModifiers())) { LOG.warn( "Can't invoke non-static 'on=" + StageEvent.BEFORE_FAIL + "' method: " + toSignatureString(entry.getKey()), t); continue; } LOG.trace( "Calling 'on=" + StageEvent.BEFORE_FAIL + "' method: " + toSignatureString(method)); try { if (entry.getKey().getParameterTypes().length == 0) entry.getKey().invoke(target); else if (entry.getKey().getParameterTypes()[0].isAssignableFrom(t.getClass())) entry.getKey().invoke(target, t); else LOG.error( "Signature of 'on=" + StageEvent.BEFORE_FAIL + "' method: " + toSignatureString(entry.getKey()) + " does not match parameter: " + t.getClass().getName()); } catch (Throwable t2) { if (t2 instanceof InvocationTargetException) t2 = t2.getCause(); LOG.error( "Uncaught errors for 'on=" + StageEvent.BEFORE_FAIL + "' method: " + toSignatureString(entry.getKey()), t2); } } if (stageObserver != null) { stageObserver.onNext( new StageChangeImpl(target.getClass(), target, Stage.FAILED, currentStage)); if (stageObserver != null) stageObserver.onError(t); } for (Class<? extends Throwable> sup : findAbsorptionLevels(target.getClass(), method)) if (sup.isAssignableFrom(t.getClass())) { LOG.trace("Absorbed " + t.getClass().getSimpleName() + ": " + t.getMessage()); return t; } throw t; } } /** * @param method * @return */ public static String toSignatureString(final Method method) { final StringBuilder result = new StringBuilder(method.getDeclaringClass().getSimpleName()) .append('#') .append(method.getName()) .append('('); boolean first = true; for (Class<?> type : method.getParameterTypes()) { if (first) first = false; else result.append(", "); result.append(type.getSimpleName()); } return result.append(')').toString(); } /** * {@link StageChangeImpl} * * @version $Id: 1ee12291a4f37aa3235547ac54195dc1d0e9bdaa $ */ private static class StageChangeImpl implements StageChange { /** */ private final Stage stage; /** */ private final String custom; /** */ private final Class<?> type; /** */ private final int hash; /** * {@link StageChangeImpl} constructor * * @param target * @param stage * @param custom */ private StageChangeImpl( final Class<?> type, final Object target, final Stage stage, final String custom) { int hashCode = -1; if (target != null) try { hashCode = target.hashCode(); } catch (final Throwable t) { LOG.warn("hashCode() failed for " + type.getName(), t); } this.type = type; this.hash = hashCode; this.stage = stage; this.custom = custom; } @Override public Class<?> getType() { return this.type; } @Override public int getHash() { return this.hash; } @Override public Stage getStage() { return this.stage; } @Override public String getCustom() { return this.custom; } @Override public String toString() { return JsonUtil.toString(this); } } /** * {@link FinalizeDecorator} * * @version $Id: 1ee12291a4f37aa3235547ac54195dc1d0e9bdaa $ * @param <T> */ private static class FinalizeDecorator<T> { /** */ private final Observer<StageChange> stageObserver; /** */ private final Class<T> type; /** */ private final T target; /** * {@link FinalizeDecorator} constructor * * @param target * @param obs * @param type */ private FinalizeDecorator( final Observer<StageChange> obs, final Class<T> type, final T target) { this.stageObserver = obs; this.type = type; this.target = target; } /** @return */ public Class<T> getType() { return this.type; } /** @return */ public T getTarget() { return this.target; } /** * WARNING! Override probably introduces severe performance issues! * * @see java.lang.Object#finalize() */ @Override public void finalize() { // LOG.trace("FinalizeDecorator called!"); if (this.stageObserver != null) this.stageObserver.onNext( new StageChangeImpl(getTarget().getClass(), getTarget(), Stage.RECYCLING, null)); for (Map.Entry<Method, Staged> entry : findEventHandlers(getType(), StageEvent.BEFORE_RECYCLE).entrySet()) { LOG.trace( "Calling 'on=" + StageEvent.BEFORE_RECYCLE + "' method: " + toSignatureString(entry.getKey())); try { invoke(this.stageObserver, null, getType(), getTarget(), entry.getKey()); } catch (final Throwable e) { LOG.warn( "Errors unhandled for 'on=" + StageEvent.BEFORE_RECYCLE + "' method: " + toSignatureString(entry.getKey()), e); } } if (this.stageObserver != null) { this.stageObserver.onNext( new StageChangeImpl(getTarget().getClass(), getTarget(), Stage.RECYCLED, null)); this.stageObserver.onCompleted(); } } /** * @param target * @param stageObserver * @param type * @return */ public static <T> FinalizeDecorator<T> from( final Observer<StageChange> stageObserver, final Class<T> type, final T target) { return new FinalizeDecorator<T>(stageObserver, type, target); } } }