Ant para desarrolladores flash – Task scriptdef (parte 5)
En este artículo vamos a crear propiedades dentro de la clase AntBasic de los artículos anteriores.
Hasta ahora hemos creado una aplicación principal llamada AntBasic, a partir de una plantilla y hemos sustituido en ella ciertos patrones, hemos hecho lo mismo con otras tres clases, (Home, Products y Contact), además hemos compilado cada una de ellas. En los siguientes ejemplos vamos a declarar tres variables dentro de la clase AntBasic, que harán referencia a las tres páginas creadas, estas variables se llamarán igual que las paginas pero toda la palabra ira en minúsculas, no como la definición de la clase que tenía la primera letra en Mayuscula.
Es un ejemplo muy sencillo, pero me viene bien para introducir el task scriptdef.
Lo primero es modificar nuestra plantilla Main.tpl, de forma que añadimos dos patrones uno que será sustituido por las variables (@properties@) y otro para añadir los imports necesarios (@imports@). Así que quedaría como sigue:
package @namespace@
{
import flash.display.Sprite;
@imports@
[SWF(width="@width@", height="@height@",frameRate="@framerate@", backgroundColor="@bgcolor@")]
public class @appname@ extends Sprite
{
@properties@
public function @appname@()
{
super();
}
}
}
Una vez que hemos modificado el fichero Main.tpl, modificamos el task (macrodef) create-main-class para que acepte dos nuevos parametros:
<macrodef name="create-main-class">
<attribute name="dir"/>
<attribute name="namespace"/>
<attribute name="name"/>
<attribute name="properties" default=""/>
<attribute name="imports" default=""/>
<sequential>
<echo message="create-page: @{namespace}.@{name}"/>
<copy file="${templates}/Main.tpl" tofile="${src}/@{dir}/@{name}.as"
overwrite="false">
<filterchain>
<replacetokens>
<token key="namespace" value="@{namespace}"/>
<token key="appname" value="@{name}"/>
<token key="properties" value="@{properties}"/>
<token key="imports" value="${imports}"/>
<token key="width" value="${width}"/>
<token key="height" value="${height}"/>
<token key="framerate" value="${framerate}"/>
<token key="bgcolor" value="${bgcolor}"/>
</replacetokens>
</filterchain>
</copy>
</sequential>
</macrodef>
la idea es tener tres propiedades distintas, una para cada página en el objeto AntBasic, como se ve sólo le paso una propiedad, así que esa propiedad tiene que contener todas las declaraciones. Para hacer esto necesito utilizar el task var, que me proporciona ant-contrib, ya que las propiedades no pueden sobrescribirse.
otra cosa que tengo que hacer es cambiar los nombres Home->home, Products->products y Contact->contact, para esto voy utilizar un scriptdef.
Task scriptdef
El task scriptdef sirve para crear nuevos task pero a diferencia de macrodef, aquí puedo utilizar diversos lenguajes (con nombres extraños), pero el que me interesa ahora es JAVASCRIPT!!!, si, puedo utilizar javascript, he probado a utilizar objetos array y date y funcionan.
Así que para cambiar el nombre de la propiedad de AntBasic, voy a declarar un scriptdef, y ha sustituir el nombre utilizando la función toLowerCase() de javascript.
<scriptdef name="lowercase" language="javascript">
<!-- parametros del task -->
<attribute name="input"/>
<attribute name="property"/>
<!-- cuerpo del task -->
<![CDATA[
name = attributes.get("property");
input = attributes.get("input");
value = input.toLowerCase();
project.setNewProperty(name, value);
]]>
</scriptdef>
la forma de definir el scriptdef es muy similar al macrodef, una primera parte donde se definen los atributos que va a admitir el task, y después el cuerpo del script. Para hacer referencia a los atributos pasados dentro del script utilizamos attributes.get(“nombre del atributo”). En este caso para devolver el valor utilizamos project.setNewProperty(“nombre de la propiedad”, “valor”).
En el ejemplo anterior hemos creado el task lowercase, que acepta dos atributos. Input, que sera el valor que queremos transformar (Home), y property, que sera el nombre de la variable a la cual asignaremos el valor pasado en input pero en minúscula. Para llamar a esta función utilizamos la siguiente instrucción:
<lowercase property="lowervar" input="${var}"/>
Sí juntamos todo, task var para concatenar y scriptdef para cambiar el nombre de la variable, el task para crear las páginas, y la clase main nos quedaría de la siguiente forma.
<target name="create-main-applications">
<echo message="create-main-applications"/>
<!-- variable donde vamos a ir concatenando los nombres de las paginas -->
<var name="pagesdef" value="//Properties"/>
<!-- variable donde vamos a meter el import, en este caso solo hay uno -->
<var name="imports" value="import ${namespace}.${pages.dir}.*;"/>
<property name="lowerpage" value=""/>
<for list="${pages}" param="page" trim="true" delimiter=",">
<sequential>
<!-- creamos las paginas, sin atributo properties, ni import -->
<create-main-class dir="${package.dir}/${pages.dir}" namespace="${namespace}.${pages.dir}"
name="@{page}"/>
<!-- creamos una variable que contendra el nombre de la página en minúscula -->
<var name="lowerpage" unset="true"/>
<!-- hacemos el cambio a minúscula -->
<lowercase property="lowerpage" input="@{page}"/>
<!-- concatenamos -->
<var name="pagesdef" value="${pagesdef}${line.separator}private var ${lowerpage}:@{page};"/>
</sequential>
</for>
<create-main-class dir="${package.dir}" namespace="${namespace}" name="${appname}"
properties="${pagesdef}" imports="${imports}"/>
</target>
Sí ejecutamos el target main ahora, veremos que la clase AntBasic, tiene tres nuevas propiedades y que se corresponden con las páginas que habíamos definido.


