/* * Quasar: lightweight threads and actors for the JVM. * Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 3.0 * as published by the Free Software Foundation. */ package co.paralleluniverse.actors; import co.paralleluniverse.fibers.SuspendExecution; import co.paralleluniverse.fibers.Suspendable; import co.paralleluniverse.strands.Strand; import co.paralleluniverse.strands.channels.QueueChannel; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * Static methods that provide access to {@link Actor}'s functionality through an {@link ActorRef} if the actor is local. * With the exception of the {@link #self()} method, application code shouldn't normally use these methods. * They are provided mainly for testing, and defining sophisticated behaviors. * <p/> * These services are provided as static methods rather than return a reference to the actor, as references to the actor * should not leak outside the actor itself. * * @author pron */ public final class LocalActor { /** * Returns the {@code ActorRef} of the actor currently running in the current strand. * * @param <T> * @param <M> * @return The {@link ActorRef} of the current actor (caller of this method) */ public static <T extends ActorRef<M>, M> T self() { final Actor a = Actor.currentActor(); if (a == null) return null; return (T) a.ref(); } public static boolean isLocal(ActorRef<?> actor) { return actor.getImpl() instanceof Actor; } @Suspendable public static void join(ActorRef<?> actor) throws ExecutionException, InterruptedException { actorOf(actor).join(); } @Suspendable public static void join(ActorRef<?> actor, long timeout, TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException { actorOf(actor).join(timeout, unit); } @Suspendable public static <V> V get(ActorRef<?> actor) throws ExecutionException, InterruptedException { return (V) actorOf(actor).get(); } @Suspendable public static <V> V get(ActorRef<?> actor, long timeout, TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException { return (V) actorOf(actor).get(timeout, unit); } public static QueueChannel<Object> getMailbox(ActorRef<?> actor) { return actorOf(actor).mailbox(); } public static Strand getStrand(ActorRef<?> actor) { return actorOf(actor).getStrand(); } public static boolean isDone(ActorRef<?> actor) { return actorOf(actor).isDone(); } public static Throwable getDeathCause(ActorRef<?> actor) { return actorOf(actor).getDeathCause(); } public static ActorMonitor getMonitor(ActorRef<?> actor) { return actorOf(actor).getMonitor(); } public static void stopMonitor(ActorRef<?> actor) { actorOf(actor).stopMonitor(); } public static void register(ActorRef<?> actor, String name) throws SuspendExecution { actorOf(actor).register(name); } public static void register(ActorRef<?> actor) throws SuspendExecution { actorOf(actor).register(); } public static void unregister(ActorRef<?> actor) { actorOf(actor).unregister(); } public static int getQueueLength(ActorRef<?> actor) { return actorOf(actor).getQueueLength(); } public static void link(ActorRef<?> actor1, ActorRef<?> actor2) { actorOf(actor1).link(actor2); } public static void unlink(ActorRef<?> actor1, ActorRef<?> actor2) { actorOf(actor1).unlink(actor2); } public static String actorToString(ActorRef<?> actor) { return actorOf(actor).toString(); } public static boolean isInstance(ActorRef<?> actor, Class<? extends Actor> type) { return type.isInstance(actorOf(actor)); } public static Class<? extends Actor> getClass(ActorRef<?> actor) { return actorOf(actor).getClass(); } public static <M, V> ActorBuilder<M, V> toActorBuilder(ActorRef<M> actor) { try { return actorOf(actor); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("ActorRef " + actor + " is not a local actor, and cannot be used as an ActorBuilder."); } } static void setMonitor(ActorRef<?> actor, ActorMonitor mon) { actorOf(actor).setMonitor(mon); } static List<Object> getMailboxSnapshot(ActorRef<?> actor) { return actorOf(actor).getMailboxSnapshot(); } static StackTraceElement[] getStackTrace(ActorRef<?> actor) { return actorOf(actor).getStackTrace(); } static void postRegister(ActorRef<?> ar) { ActorImpl impl = ar.getImpl(); if (!(impl instanceof Actor)) return; ((Actor) impl).postRegister(); } private static Actor actorOf(ActorRef<?> ar) { ActorImpl impl = ar.getImpl(); if (!(impl instanceof Actor)) throw new IllegalArgumentException("ActorRef " + ar + " is not a local actor."); return (Actor) impl; } private LocalActor() { } }