Introduction

Flash is a lightweight cross-platform runtime for rich media, enterprise applications and mobile applications, as well as an integrated development environment. Flash can be programmed in ActionScript 1/2/3.

Wednesday, May 26th, 2004 at 8:15 pm

as2lib: Reflections

The ones that are coming from a Java background probably know what Reflections are. For the others here’s a little explanation:
Reflections offer support to find out information about every kind of member inside a programming environment. Members are for example Classes, Interfaces, Packages, Methods, Properties and so on. As you probably have already imagined the as2lib offers such a Reflection API. It is located in the org.as2lib.env.reflect package. Click the following link to see a little class diagram that shows how all these classes are related to each other: Reflections: Class Diagram.
To obtain a ClassInfo instance representing a specific class you use the org.as2lib.env.util.ReflectUtil’s getClassInfo(Function/Object) operation. The operation for packages is respectively called getPackageInfo(Object). You can now work with this ClassInfo or PackageInfo instance to find out more information like the name of the class, the class’s methods an so on. The above diagram shows all the available operations. [It is that simple to work with that I will not show an example. Just play a little bit around with it.]
Edit: Read on to see the power of the Reflections API.

Create a little package hierachy ‘org.swacker’ and put the following dummy classes into the ’swacker’ package.

  1. import org.swacker.DummySuperClass;
  2.  
  3. class org.swacker.DummyClass extends DummySuperClass {
  4.     public function DummyClass(Void) {
  5.     }
  6.     public function methodOne(Void):Void {
  7.     }
  8.     public function methodTwo(Void):Void {
  9.     }
  10. }
  1. class org.swacker.DummySuperClass {
  2.     public function DummySuperClass(Void) {
  3.     }
  4. }

These two classes are only here for demonstration. They have no real usage. Create a new fla and put the following code into the first frame.

  1. import org.as2lib.env.util.ReflectUtil;
  2. import org.as2lib.env.reflect.ClassInfo;
  3. import org.as2lib.env.reflect.MethodInfo;
  4. import org.as2lib.data.holder.Map;
  5. import org.as2lib.data.iterator.Iterator;
  6. import org.swacker.DummyClass;
  7.  
  8. var dcClassInfo:ClassInfo = ReflectUtil.getClassInfo(DummyClass);
  9.  
  10. trace("Class Name                : " + dcClassInfo.getName());
  11. trace("Class Full Name           : " + dcClassInfo.getFullName());
  12. trace("Super Class Name          : " + dcClassInfo.getSuperType().getName());
  13.  
  14. var methodMapIterator:Iterator = dcClassInfo.getMethods().iterator();
  15. while (methodMapIterator.hasNext()) {
  16.     trace("Method Name               : " + MethodInfo(methodMapIterator.next()).getName() + "()");
  17. }
  18.  
  19. trace("Parent Package Name       : " + dcClassInfo.getParent().getFullName());
  20. trace("Parent Parent Package Name: " + dcClassInfo.getParent().getParent().getFullName());

Compile and run the swf. You should get the following output:

  1. Class Name                : DummyClass
  2. Class Full Name           : org.swacker.DummyClass
  3. Super Class Name          : DummySuperClass
  4. Method Name               : methodTwo()
  5. Method Name               : methodOne()
  6. Parent Package Name       : org.swacker
  7. Parent Parent Package Name: org

As you can see everything worked out fine and we got all the information we wanted.
If you encounter problems check that you have downloaded the as2lib and added it to your classpath. You also have to add the package you currently created.

4 Responses to “as2lib: Reflections”

  1. Leo Vildosola

    I tried to use the reflection functionality and I cannot get it to work. Maybe you can help me. The sample you give works fine but it is not relevant to my case. My use of reflection is not only to be able to extract information about a class, but more to be able to function with that class dynamically.

    My scenario uses Flash components. I create a custom component that has two properties, event and eventHandler, that allow me to group processing of events in a single AS2 class. “event” has the name of an event that the component will raise whenever a particular action is performed by the user. Say we call this event “youPushedMe.” “eventHandler” is the fully qualified path to an AS2 class that will serve as the handler of that event. Say we call this class “org.swacker.EventHandler.”

    Using the EventDispatcher logic we can make EventHandler a listener for the given event. To make EventHandler work we add a method called youPushedMe to handle the event. In order register EventHandler as a listener I need to create an instance of the class dynamically, but from within another AS2 class, not from within a frame, or event triggered by a frame. This scenario does not work with the current reflection functionality, or at least I cannot make it to work. ReflectUtil.getClassInfo(”org.swacker.EventHandler”); throws an exception. Since the property eventHandler from my component is a string, then I don’t think this works. I also tried changing the property’s type to Function and it still does not work. Any ideas?

  2. Leo Vildosola

    BTW, I read some more while researching my problem. If I create a Symbol called org.swacker.EventHandler and associate it to class org.swacker.EventHandler and export it on the first frame, then Flash finds it and my code works fine. I guess this is a Flash problem more than the ReflectUtil problem. Adding something like an import statement in one of my frames won’t cut it. Do you know of a workaround?

  3. Leo Vildosola

    A little update. Since I did not want to force the creation of Symbols to force the Flash movie to refer to specific classes, I figured it would be cleaner to simply add a static method called say preload and call it from a frame in the movie. That way I can keep this type of initialization in one place. This works fine also.

  4. Simon Wacker

    Yeah, that’s a flash problem. The class will be initialized as soon as you use it. That means if you do the following:

    import org.swacker.EventHandler;
    ReflectUtil.getClassInfo(”org.swacker.EventHandler”);

    the class won’t be found and an exception will be thrown because org.swacker.EventHandler is not contained in the _global path.
    Thus what you have to do is just referencing the class. Like this:

    import org.swacker.EventHandler;
    org.swacker.EventHandler;
    ReflectUtil.getClassInfo(”org.swacker.EventHandler”);

    If you now compile and run all should work out fine.