HTML in Flash/Flex

I was mandated at work to work on the company’s website. Since the site needs to incorporate a blog for several employees, the option of writing the whole site in Flash was out of the question, as people would embed whatever videos from YouTube, images from various places, etc. The support for HTML rendering with Flash Player is fairly limited.

Not anymore! Today, I decided to simply Google Flash HTML renderer and I come across this little marvel: http://code.google.com/p/htmlwrapper/. It’s a fairly advanced HTML renderer. It supports most of the features that one would need on a blog. I have yet to try this library, but I sure will as soon as I can. This puts the idea of writing the whole site with Flash and GAIA Framework back in the run!

Hope you enjoy this library!

Developing for Google Wave

Hi! I don’t know how many of you had the chance to play with Google Wave at all, but I had the opportunity to fool around with it a bit. I’m quite amazed of how things turned out, even though their interface needs quite a bit of work. The overall performance of the system is a little disappointing, but I try to keep in mind that this is only a preview version. As soon as it hits the beta stage, I think we’ll see some major improvement across the board.

Even though the system is only an alpha version (or preview, call it what you will), Google still released some information on how to develop for it. I will go over two different aspects of Google Wave development, which are gadgets and robots.

Gadgets

Google Wave gives you the possibility to add gadgets to  your waves. They’re used to display some custom data, for example, a Google Map gadget. You can pass it parameters and Google Wave will add an interactive Google Map within your Wave posts. The beautiful part? They all use shared states. That means that, whoever is participating in your wave has access to control your gadget and interact with it. Even pass in new parameters. They opened the API to developers so you can develop your own gadgets. They chose to use XML to deliver the gadget content. The gadget itself is HTML and JavaScript. Here is an example of a shared state gadget that simply increments a counter:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="State Example" height="120">
  <Require feature="wave" />
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div" style="height: 50px;"></div>
    <script type="text/javascript">

    var div = document.getElementById('content_div');

    function buttonClicked() {
      var value = parseInt(wave.getState().get('count', '0'));
      wave.getState().submitDelta({'count': value + 1});
    }

    function stateUpdated() {
      if(!wave.getState().get('count')) {
        div.innerHTML = "The count is 0."
      }
      else {
        div.innerHTML = "The count is " + wave.getState().get('count');
      }
    }

    function init() {
      if (wave && wave.isInWaveContainer()) {
        wave.setStateCallback(stateUpdated);
      }
    }
    gadgets.util.registerOnLoadHandler(init);

    // Reset value of "count" to 0
    function resetCounter(){
      wave.getState().submitDelta({'count': '0'});
    }

    </script>
    <input type=button value="Click Me!" id="butCount" onClick="buttonClicked()">
    <input type=button value="Reset" id="butReset" onClick="resetCounter()">
  ]]>
  </Content>
</Module>

Now, with this gadget, everyone participating in a wave can click on the button and increment the counter. But, that is only one part of the gadget. You need to host this code somewhere on a public web server in order for Google to be able to reach it. Now that you’re done writing the code, let’s save that file as “buttonShared.xml” and host it somewhere. Now, to insert this gadget into a Google Wave post, click on the Add Gadget by URL button and enter the full path to the “buttonShared.xml” file. You should see your button and the label next to it appear in your wave.

If you are a registered developer for Google, you can also install Extensions. Extensions are basically installers for gadgets. All you have to do is write a manifest XML file with the information about your gadget, where you want it to reside in Google Wave and the path to the gadget. Here’s an example manifest file for our button gadget:

<extension
    name="Button Gadget"
    thumbnailUrl="http://your.url.here/path/to/screenshot_buttongadget.png"
    description="Get everyone to click your button. See how high you can go!">
  <author name="Your name here"/>
  <menuHook location="toolbar" text="Add Button Gadget"
      iconUrl="https://your.url.here/path/to/icon_insertButton.png">
    <insertGadget url="http://your.url.here/path/to/buttonShared.xml"/>
  </menuHook>
</extension>

Google Wave will then insert your button to your interface toolbar and you can directly click on it to insert a button to your wave. There’s a whole series of actions you can do with those extensions that I will not post here. You can refer to the link section at the end of this post to get the full Google page about these examples.

Robots

Robots are an interesting concept in Google Wave. They are participants in a wave. They can be silent or they can be interactive. They have total control of the wave. If you want the robot to, for example, post certain things on Twitter, all you have to do is add it to the wave and it’ll start doing its thing. The way you register robots for Google Wave is through Google App Engine. Please refer to my post about Google App Engine and BlazeDS for how to setup the Google App Engine plugin for Eclipse and get started with a project.

You will need the Google Wave library. You can find it at http://code.google.com/p/wave-robot-java-client/downloads/list. You will need them all so go ahead and download all the JAR files.

Once you have your Google App Engine project setup, written, compiled and deployed to Google App Engine, simply add a new contact to your list. The contact will be <application-id>@appspot.com. For example, I’ll call mine “mytweetbot”, so the contact I will be adding to my list is mytweetbot@appspot.com.

For the sake of this example, I will simply use Google’s example for a simple bot called Parroty. Create a new Google project and call it Parroty. Go ahead and set the package to “parroty”. Once you created your project, copy the downloaded JAR files to your /war/WEB-INF/lib directory.

Create a new class in /src/parroty called ParrotyServlet. In the Create new class dialog, click on the “Browse” button next to the Superclass and search for AbstractRobotServlet. It should be in the com.google.wave.api package. Make sure you got the Inherited Abstract Methods and Generate Comments checked and click Finish.

By default, the superclass will add the processEvents method. That’s your entry point for your robot. Here, we’ll simply make the bot repeat everything said on the wave.

package com.google.wave.api.samples;

import com.google.wave.api.*;

public class ParrotyServlet extends AbstractRobotServlet {

    @Override
    public void processEvents(RobotMessageBundle bundle) {
        Wavelet wavelet = bundle.getWavelet();

        if (bundle.wasSelfAdded()) {
            Blip blip = wavelet.appendBlip();
            TextView textView = blip.getDocument();
            textView.append("I'm alive!");
        }

        for (Event e: bundle.getEvents()) {
            if (e.getType() == EventType.WAVELET_PARTICIPANTS_CHANGED) {
                Blip blip = wavelet.appendBlip();
                TextView textView = blip.getDocument();
                textView.append("Hi, everybody!");
            }
        }
    }
}

In Google’s terms, a Bundle is the whole wave information, the Wavelet is what contains the wave Blips, a Blip is an entry on a wave and the TextView is an object you put in a Blip to render text.

In order to make your robot react to certain events happening on the wave, you need to tell your robot what to listen to. To do that, create a new directory in your /war directory called “_wave”. In this new directory, create an XML file called “capabilities.xml”. This file should look like this:

<?xml version="1.0" encoding="utf-8"?>
<w:robot xmlns:w="http://wave.google.com/extensions/robots/1.0">
  <w:capabilities>
    <w:capability name="WAVELET_PARTICIPANTS_CHANGED" content="true" />
  </w:capabilities>
  <w:version>1</w:version>
</w:robot>

This tells your robot to be listening to the WAVELET_PARTICIPANTS_CHANGED event.

The only thing remaining is to map our servlet. By default, Google Wave will look for the /_wave/robot/jsonrpc servlet to interact with your robot. Let’s map our class to that servlet:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <servlet>
        <servlet-name>Parroty</servlet-name>
        <servlet-class>parroty.ParrotyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Parroty</servlet-name>
        <url-pattern>/_wave/robot/jsonrpc</url-pattern>
    </servlet-mapping>
</web-app>

This part is optional, but it’s also cool. You can provide a bean to your robot with its user profile. Here’s the code to the profile servlet for the Parroty robot:

import com.google.wave.api.ProfileServlet;

public class Profile extends ProfileServlet {
    @Override
    public String getRobotName() {
        return "My Robot Name";
    }

    @Override
    public String getRobotAvatarUrl() {
         return "http://My Robot Image URL";
    }

    @Override
        public String getRobotProfilePageUrl() {
        return "http://My Robot Profile URL";
    }
}

Since everything with the Google Wave robots are versioned, you need to increment your <w:version> tag in the “capabilities.xml” file to tell Google Wave that something changed. Otherwise, it’ll be cached and you’ll have to wait until the cache is refreshed to see your changes. Same thing if you want to change the set of events you want your application to listen to.

Now, all what’s left is to deploy your application to Google App Engine, and add your new contact as a participant TO A NEW WAVE. This is important. It won’t work properly if you just add the bot to an already existing wave.

Links

Wave Gadget Guide: http://code.google.com/apis/wave/extensions/gadgets/guide.html
Wave Gadget Reference: http://code.google.com/apis/wave/extensions/gadgets/reference.html
Extensions Guide: http://code.google.com/apis/wave/extensions/installers/index.html.
Java Client API Tutorial: http://code.google.com/apis/wave/extensions/robots/java-tutorial.html
Java Client API Reference: http://wave-robot-java-client.googlecode.com/svn/trunk/doc/index.html

I hope you find that information useful! Please feel free to comment and/or ask questions, I’ll try to answer as quickly as possible.

For those who are interested in developing for Google Wave but don’t have an invite yet, I have a limited amount of them. Please reply to this post with your email address and I’ll send you an invite. I have to add that you need to have a Gmail account to register to Google Wave.

Thanks for reading!

Simon

Zend Framework 2.0

Zend announced back in November of 2009 that the next major release of Zend Framework was on the way. They published the new framework’s roadmap and some of the new features. The upcoming release of Zend Framework has PHP 5.3 as a requirement, as it relies on namespace support. The main changes to Zend Framework is the MVC implementation, but there are many architectural and design changes as well. Here’s a summary of the new features.

The goal of Zend Framework is to improve the overall consistency, more consistent APIs relating to constructors, options and exceptions.

  • Unified constructor. All constructors will (optionally) accept an array for options or Zend_Config object as the first argument. This allows for more flexibility to add new arguments to the constructor, have a variable number of arguments and allow “named” arguments. Additionally, it’s a good technique for allowing Dependency Injection. As part of the initiative, most components will also have a “setOptions()” method to which the options array will be passed  (and which may be used later to reset object state). Typically, this will proxy to other setters. Many components in Zend Framework 1.x already do this: Zend_Application, Zend_Form, Zend_Validate, Zend_Layout, etc. We are simply extending this paradigm to cover all components. In order to reduce code duplication, we will likely introduce a zend\Options class, which will work roughly as follows:
    namespace zend;
    class Options
    {
        public static function setOptions($object, array $options)
        {
            if (!is_object($object)) {
                return;
            }
            foreach ($options as $key => $value) {
                $method = "set" . self::_normalizeKey($key);
                if (method_exists($object, $method)) {
                    $object->$method($value);
                }
            }
        }
    
        public static function setConstructorOptions($object, $options)
        {
            if ($options instanceof Zend_Config) {
                $options = $options->toArray();
            }
            if (is_array($options)) {
                self::setOptions($object, $options);
            }
        }
    
        protected static function _normalizeKey($key)
        {
            $option = str_replace('_', ' ', strtolower($key));
            $option = str_replace(' ', '', ucwords($option));
            return $option;
        }
    }
    
    use zend\Options as Options;
    class Foo
    {
        public $bar = '';
        public $baz = '';
    
        public function __construct($options = null)
        {
            Options::setConstructorOptions($this, $options);
        }
    
        public function setOptions(array $options)
        {
            Options::setOptions($this, $options);
        }
    
        public function setBar($value)
        {
            $this->var = $value;
        }
    
        public function setBaz($value)
        {
            $this->baz = $value;
        }
    }
    
    $foo = new Foo(array('bar' => 'baz'));
    echo $foo->bar; // "baz";
    
    $foo->setOptions(array('bar' => 'boo', 'baz' => 'bat'));
    echo $foo->bar . $foo->baz; // "boobat";
    
  • Options. In Zend Framework 1.x, the various components which accept options accept a variety of formats: some expect underscore_separated keys, other expect camelCasedKeys, others expect UPPERCASEDKEYS, and some expect lowercasedkeys. This leads to confusion for many, and also leads to difficulties debugging. The goal in Zend Framework 2.0 is to standardize option keys to correct this situation. Currently, they are leaning towards all_lowercase_underscode_keys. These are human-readable, contain only valid PHP variable characters, and make for a simplified option parsing implementation. Additionally, it is trivial to translate keys to camelCase (“str_replace(‘ ‘, ”, ucwords(str_replace(‘_’, ‘ ‘, $value)))”) for purposes of overloading – and this makes it easy to document option key => class property affiliations.
  • Exceptions. Each component will have an Exception marker interface, with exceptions defined for discrete exception types thrown by the component. The concrete exceptions will either extend the global Exception class or an SPL Exception, and also implement the component Exception interface. This allows to throw appropriate SPL exceptions while retaining a common Exception type (via the marker interface). As an example:
    namespace \Foo\Bar;
    interface Exception
    {
    }
    
    class InvalidArgumentException extends \InvalidArgumentException implements Exception
    {
    }
    
    try {
        throw new InvalidArgumentException();
    }
    catch (\Foo\Bar\Exception $e) {
    }
    
  • Design By Contract. They will be altering portions of the framework to follow the concept of design by contract, and new development will follow this paradigm. At first, this will take the form of refactoring to add interfaces/refactoring interfaces to reflect actual usage.
    Interfaces make creating alternate implementation of standard classes easier, while assuring that these implementations will continue to work with the classes that consume them. In many cases currently, they offer only abstract classes, with no equivalent interfaces; in other cases, the consuming classes use methods that are not part of the interface.
    In addition to this initiative, they will be eliminating some functionality intended to add flexibility to some of the standard classes. They have found that oftentimes this functionality leads to performance overhead as well as consumes maintenance time that could be used better elsewhere in the framework. As an example, the Dispatcher has a number of methods for adding custom class -> file mappings that are largely used and which use an unnecessary number of CPU cycles; refactoring this to follow only the standard use cases would ease maintenance, while having a good, simple interface would make creating alternate implementations for custom use cases easier.
  • Elimination of most singletons. Zend Framework has often been accused of “singletonitis”. While they’re not sure if they completely agree, in most cases, the singletons they have have presented a number of problems and led to difficult test cases. Additionally, in most cases, the singletons is unwarranted. They will be refactoring to eliminate these, including in Zend_Controller_Front. In exceptional cases, they will keep them; these include global operations such as autoloading and database connections.
  • Creation of components for general-purpose, cross-functional actions. A Number of components duplicate code, and they want to push the duplication areas into discrete components that the original components may then consume. Some of these include:
    • Plugins/Helpers/Strategies (seen currently in Zend_Controller_Front, Zend_Controller_Action_Helper, Zend_View (helpers and filters), Zend_Form (validators, filters and decorators), etc). Plugin discovery and loading could benefit from a common API.
    • Decorators (seen in Zend_Form; other areas could benefit from the pattern)
    • Factories (seen currently in Zend_Db, Zend_Navigation_Page, Zend_Auth, Zend_Translate, Zend_Cache, etc)
    • Caching (seen currently in Zend_Translate, Zend_Locale, Zend_Queue, Zend_Paginator, Zend_Feed_Reader, Zend_Db_Table, etc.)
  • Usage of new language features within plugin architectures. Currently, most plugins rely on the strategy pattern, but the mechanism differs between plugins. PHP 5.3 offers some compelling alternatives that they want to explore: __invoke() and closures. Closures are less compelling as we cannot do simple type-hinting on them. __invoke() offers perhaps the simplest solution, and could become a standard API for plugins.
  • Autoload-only. They will move to using autoloading throughout the framework. This solves a number of performance issues, as well as simplifies coding dependencies (particularily exceptions).
  • Namespaces. PHP namespaces benefit frameworks and libraries more than any other code bases, and Zend Framework can benefit from it greatly, particularily with components such as Zend_Search_Lucene and Zend_Controller. However, adopting namespaces does not come without a cost: all code will need to be rewritten to define and use namespaces. This will be the single biggest BC break they introduce.
    They also plan to introduce a separate namespace for unit testing, and are currently looking at either \test\zend, \zend\test, or \testzend. This, along with per-component namespaces, will help prevent naming collisions within the test suite.
  • goto. Goto is often considered “evil”, but is invaluable when creating Finite State Machines (FSM) and parsers; usage of goto will be evaluated on a case-by-case basis. Some examples of components that could potentially benefit from such an implementation include Zend_Search_Lucene (which already implements a FSM), the MVC (more below), Zend_Ical, and Zend_Markup (though not all of these may make use of it).
  • Specifics on Plugin architecture changes

For the MVC changes, there is a great article on Pádraic Brady’s Blog.

You can also find all the information about this new version of Zend Framework on Zend’s website at http://framework.zend.com/wiki/display/ZFDEV2/Zend+Framework+2.0+Roadmap.

Timers vs Enter Frame

I was working on a project not too long ago where the original developer was using Timers to time his animations and events firing. It resulted in a pretty horrific view when the app was run on a slower computer. All timings were off, events were not fired, or fired late, even, in some cases, in advance. I did a little bit of research and found this article: http://www.bit-101.com/blog/?p=910.

In this article, Keith Peters demonstrate that there is a misconception with the Timer theory of “a millisecond is a millisecond”. A lot of people rely on this theory to justify the use of Timers at the base of their applications.

Enjoy!

PHP Error Handler

Hey, I thought about sharing this little piece of code. Back a couple years, I was heavily involved with PHP projects. I came up with the idea of writing an error handler class system that would allow me to add custom errors and return Boolean values from class methods and functions. It also had a method to list errors in a cleaner way than PHP’s default error handler. Here’s the concept behind it.

The way I designed this system is using a Singleton pattern to accumulate errors. By using a static variable, PHP stores this object in memory and can be referred to at a later time. Of course, there’s no real instance creation prevention in PHP, so we’ll skip the part of declaring a private constructor.

class Error {
    private $errorList;
    private $errorCount;

    public function getInstance() {
        static $errobj;
        if (!is_object($errobj) || !is_a($errobj, 'Error')) {
            $errobj = new Error();
        }
        return $errobj;
    }

    public function raise($errCode, $errString, $errType = "general") {
        $errobj = self::getInstance();
        $errobj->errorList[$errType][(int)$errobj->errorCount]['code'] = $errCode;
        $errobj->errorList[$errType][(int)$errobj->errorCount]['message'] = $errString;
        $errobj->errorCount++;
    }

    public function errorOccured() {
        $errobj = self::getInstance();
        if ($errobj->errorCount > 0) {
            return true;
        }
        else {
            return false;
        }
    }

    public function getList() {
        $errobj = self::getInstance();
        return $errobj->errorList;
    }
}

Now that we have the base of our error handler class, we can create new classes that extend that master class. Here’s an example:

class ErrorDB extends Error {
    public function raise($db_exception, $message) {
        parent::raise(E_USER_WARNING, $message . "\r\n" . $db_exception->getMessage(), "database");
    }
}

This class will use the parent’s “raise” method to add the error to the error stack. Note that the last argument, “database” is the category in which this error will appear under. Here’s an example of how to use this class. Let’s assume that you already have a PDO database object.

<?php

    try {
        // Database operation here
    }
    catch (PDOException $e) {
        ErrorDB::raise($e, "Cannot perform database operation 'xyz'");
    }

?>

Next, I’ll show you how to handle PHP’s native errors with the same system.

class ErrorPHP extends Error {
    public function raise($errno, $errstr, $errfile, $errline) {
        // We don't really care about E_STRICT errors
        if ($errno != E_STRICT) {
            parent::raise($errno, $errstr . " (in " . $errfile . ", at line " . $errline . ")", "PHP Errors");
        }
    }
}

set_error_handler("phperror");

function phperror($errno, $errstr, $errfile, $errline) {
    ErrorPHP::raise($errno, $errstr, $errfile, $errline);
}

Once the page is done loading, you can call the getList() statically from Error, like $errors = Error::getList();, to return a multi-dimensional array containing all the errors that occured. You’re free to display it anyway you’d like.

I hope you find this article useful!
Thanks for reading.

Happy New Year!

I’d like to wish everyone a happy new year and a successful year 2010!

For my part, I’ll try and post more articles and tutorials. That is my new year’s resolution!

Cheers!

GAE/J and Flex – New tutorial

Hey all, here’s a new tutorial on how to use the Google App Engine/Java and BlazeDS for Flex.

Note that not all the credit belongs to me, as I found a lot of information on the web. I would like to thank Martin Zoldano (http://martinzoldano.blogspot.com) for the recompiled flex-messaging-core.jar file.

Enjoy!

Read more…

AMF Tutorial part 3 added

Hey! I finally took the time to write up the last part of my AMF tutorial.

Hope it answers your questions!

-Simon

Read More

AMF Tutorial part 2 added

I know, I was supposed to write to my blog more often than this, but I was pretty busy. Anyway, here it is! You can access it through the Tutorial link at the top of the page!

Enjoy!

PS: Feel free to leave any feedback.

Read more

Number Formatting with AS3

I ran into a problem the other day where, I’m pretty sure a lot of you actually ran into as well, number formatting with AS3.

The big problem is that Math.round doesn’t allow you to specify a precision.

I tried to make this function work as closely as PHP’s number_format() function, here’s my attempt:

function numberFormat(num:Number, decimals:int = 0, thousands:String = ','):String
{
	var buffer:String = '';
	var truncate:Number = 0;
	var orig:String = '';
	if (decimals > 0) {
		var ratio:int = Math.pow(10, decimals);
		var tempDecimal:Number = (Math.round(num * ratio) / ratio);
		truncate = (Math.round((tempDecimal - Math.floor(num)) * ratio) / ratio);
		if (truncate == 1) {
			num += 1;
			truncate = 0;
		}
		orig = Math.floor(num).toString();
	}
	else {
		orig = Math.round(num).toString();
	}

	var iteration:int = 0;

	for (var i = (orig.length - 1); i >= 0; i--) {
		if (((iteration % 3) == 0) && (iteration > 0)) {
			buffer = thousands + buffer;
		}
		buffer = orig.charAt(i) + buffer;
		iteration++;
	}

	if (truncate > 0) {
		buffer += '.' + truncate.toString().substr(2);
	}

	return buffer;
}

Hopefully, it helps you resolve your number formatting issues.