The Source for Java Technology Collaboration
User: Password:



Kirill Grouchnikov

Kirill Grouchnikov's Blog

The real story about how Anakin Skywalker became Darth Vader

Posted by kirillcool on May 28, 2005 at 01:54 PM | Comments (16)

Here it is - the JDK 5.0-compliant story behind "Revenge of the Sith". See it in all its glory, using the new java.util.concurrency package:
public class Princess implements ExecutorService {
   public static final Princess PADME = new Princess();

   // private member
   private StarShip ship;

   private Princess() {
     this.setDefaultLocale(Locale.EN);
     Timer timer = new Timer();
     TimerTask task = new TimerTask() {
       public void run() {
         Princess.this.changeHairStyle();
         Princess.this.changeClothes();
       }
     };
     timer.scheduleAtFixedRate(task, new Date(), 1000);
   }
}

public class JediKnight implements ExecutorService {
   public static final JediKnight ANAKIN = new JediKnight(false);
   public static final JediKnight OBI_WAN = new JediKnight(false);
   public static final JediKnight YODA = new JediKnight(true);

   private JediKnight(boolean isYoda) {
     if (!isYoda) {
       this.setDefaultLocale(Locale.EN);
     }
     else {
       Locale yodaLocale = Locale.EN;
       this.setDefaultLocale(Utils.shuffle(yodaLocale));
     }
     this.setLightSabre(LightSabreFactory.getInstance());
     this.setGoodLooking(!isYoda);
   }
}

public class Sith {
   public static final Sith LORD = new Sith();

   private Sith() {
     this.setDefaultLocale(Locale.EN);
     this.setClothes(DarkRobeFactory.getInstance());
     this.setLightSabre(LightSabreFactory.getInstance());
   }
}

public static main() {
  // The following line has been commented out so as not
  // to confuse fans who never did it 
  
  // Utils.initChildren(JediKnight.ANAKIN, Princess.PADME);

  // Use JDK 5.0 concurrency package
  Future<Set<Child>> padmeFuture = Princess.PADME.submit(
    new Callable<Set<Child>>() {
      public Set<Child> call() {
        try {
          int weeks = (int)(36+4.0*Math.random());
	  wait(weeks*7*24*60*60*1000);
          this = null;
          System.gc();
        }
        finally() {
          Child boy = new Child("Luke");
          Child girl = new Child("Leia");
          Set<Child> result = new HashSet<Child>();
          result.add(boy);
          result.add(girl);
          return result;
        }
      }
    }
  );

  if (JediKnight.ANAKIN.poll(padmeFuture) instanceof ThreadDeath) {
    JediKnight.ANAKIN.alarm();

    // use some marketing ideas
    Sith.LORD.promise(JediKnight.ANAKIN, new RuntimePermission("object.restore.afterGC"));
    Sith.LORD.promise(JediKnight.ANAKIN, new RuntimePermission("force.power.dark.*"));
    Sith.LORD.promise(JediKnight.ANAKIN, new RuntimePermission("force.power.*"));
    Sith.LORD.promise(JediKnight.ANAKIN, new RuntimePermission("force.*"));

    JediKnight.ANAKIN.setInternalName("Darth Vader");

    JediKnight.ANAKIN.promise(Princess.PADME, new RuntimePermission("*")); 

    Princess.PADME.alarm();
    Princess.PADME.boardShip();

    // Use JDK 5.0 concurrency package
    Future<StarShip> anakinFuture = 
      JediKnight.OBI_WAN.submit(
        new Callable<StarShip>() {
          public RuntimePermission call() {
            try {
              Class princessClass = Princess.getClass();
              Field shipField = princessClass.getDeclaredField("ship");
              // will never throw SecurityException on Jedi Knight
              shipField.setAccessible(true);
              JediKnight.this.add(new RuntimePermission("object.ship.board.*"));
              return (StarShip)shipField.get(Princess.PADME);
            }
            catch (SecurityException se) {
              // never supposed to happen to Jedi Knight
              System.out.println("Internal error. Contact George Lucas.");
              System.reboot();
            }
          }
        }
      );

    StarShip padmeShip = anakinFuture.call();
    padmeShip.put(JediKnight.OBI_WAN);

    JediKnight.ANAKIN.see(Princess.PADME);
    Princess.PADME.removeLove(JediKnight.ANAKIN);

    JediKnight.ANAKIN.see(JediKnight.OBI_WAN);
    JediKnight.ANAKIN.removeLove(Princess.PADME);
    
    JediKnight.OBI_WAN.removeLimbs(JediKnight.ANAKIN);
    // note - absolutely no need for GC, Anakin will be collected automatically.

    ReferenceQueue<JediKnight> sithWatchList = new ReferenceQueue<JediKnight>();
    PhantomReference<JediKnight> anakinRef = sithWatchList.remove();
    JediKnight anakinPhantom = anakinRef.get();

    Sith DARTH_VADER = Sith.LORD.assemble(anakinPhantom, LimbFactory.getSpareInstances());
    MouthPiece newMouthPiece = MouthPieceFactory.getInstance();
    // no need to check that it works - guaranteed to work with no noise
    DARTH_VADER.add(newMouthPiece);
    DARTH_VADER.rise();
  }
  else { 
    // TODO - create alternative scenario for Sith revenge
  }
}

Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • :D Brilliant

    Posted by: aidan_walsh on May 30, 2005 at 01:00 AM

  • where are the other episodes ? :)

    Posted by: aiqa on May 30, 2005 at 10:25 PM

  • Your really gonna make me go get a bunch of JDK 5.0 books from Barnes & Noble aren't you?

    * sigh *

    purchase.book(Bruce.debit(CHECKING_ACCT, $89.95));

    Now that Apple has 5.0 released I have no excuse.

    Posted by: bbjwerner on May 31, 2005 at 01:31 AM

  • public static final Princess PADME = new Princess(); :-D

    Posted by: akieden on May 31, 2005 at 04:44 AM

  • akieden,
    I hope you didn't try to compile the program... Because otherwise i'll have to charge 8 dollars for each execution.

    Posted by: kirillcool on May 31, 2005 at 05:16 AM

  • Thanks for the concise spoiler :)

    Posted by: angsuman on May 31, 2005 at 09:09 AM

  • angsuman,
    You were warned that it contained spoilers :)

    Posted by: kirillcool on May 31, 2005 at 09:13 AM

  • Yoda Locale?

    private JediKnight(boolean isYoda) {
    this.setDefaultLocale(!isYoda ? Locale.EN : Locale.EN_YO);

    There should be a best of the weblogs award...I'd nominate this post!

    Posted by: phlogistic on May 31, 2005 at 02:11 PM

  • *Lol* Good looking not is Yoda... priceless. Q: what do the lines of code with Princess.this. in them do? Is it some special construct because the code is placed inside an inner class??? Is it a new 1.5ism??

    Posted by: rickcarson on May 31, 2005 at 02:30 PM

  • rickcarson,
    Just a convinient way to obtain pointer to the outer class without passing its instance as a parameter. It was in the language before 5.0

    Posted by: kirillcool on May 31, 2005 at 09:18 PM

  • ЭТА ПЯТЬ! Аффтар жжот!

    Posted by: tux81 on June 03, 2005 at 05:38 AM

  • Very nice! Any reason why you did not use enumeration(s)? Seems the same pattern to me.

    Posted by: rbirenheide on June 06, 2005 at 03:37 AM

  • No reason not to use them, it just slipped my mind.
    You can write something like
    public enum Robot {
        R2D2 {
          public void native speak();
        },
        C3PO {
          public void speak() {
            ...
          }
        }
    }
    

    Posted by: kirillcool on June 06, 2005 at 03:43 AM

  • Loved it, but i don't agree with the removeLove methods ;^) JediKnight.ANAKIN.see(Princess.PADME); Princess.PADME.removeLove(JediKnight.ANAKIN); JediKnight.ANAKIN.see(JediKnight.OBI_WAN); JediKnight.ANAKIN.removeLove(Princess.PADME);

    Posted by: danielmd on June 29, 2005 at 07:31 AM

  • You forgot to include the comments for documentation. /** * STAR WARS * The revenge of the Sith * @version III * @author Little Gorge * * etc. * */ And also public abstract class LordSith extends Sith implements DarkSide { /*Should be 66 by default.*/ protected boolean executeOrder(int order) throws OrderExecutionException; public LordSith getSithWithUglyFace(); }

    Posted by: amigosdemaurilio on July 05, 2005 at 01:51 PM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds