星期一
16

一、 解决方案

 

 A. 方案简述

解决方案的所要实现的目的很简单,即通过简单的配置发送邮件内容及附件到指定邮件地址。

解决方案使用Apache Ant工具。Apache Ant是由Apache软件基金会所提供的开源工具,一般用于Java环境中。

解决方案适用于Windows,但是通过修改.bat文件为.sh文件,解决方案也可以适用于Unix/Linux。

 

 B. 邮件服务器

邮件服务器必须处于邮件发送端所能连接的网络内,且必须支持SMTP协议。

无论是否支持匿名发送,无论是否要求加密连接(SSL),程序都可以正常运行。

额外需要注意的是:

1) 配置文件中将明码列出邮件账户密码,所以不应使用个人邮箱(包括个人的企业邮箱)。

2) 应当确认账户密码不会过期,否则必须定期人工修改配置文件中以确保密码正确。

邮件服务器的配置具体见配置文件的说明。

 

 C. 软件要求

解决方案用到了以下内容:

1) JDK 5.0+

Java运行环境。该软件可以在Hyperion/Oracle/Informatica等几乎所有非微软系软件中找到,也可以单独下载。

下载地址:

http://www.oracle.com/technetwork/java/javaee/downloads/index.html

2) Apache Ant 1.6+

Apache开源工具。该软件可以在Hyperion/Oracle/Informatica等大部分非微软系软件中找到,也可以单独下载。

下载地址:

http://ant.apache.org/bindownload.cgi

3) activation.jar & mail.jar

Java邮件发送所需要的两个类包。分别包含于JavaMail和JAF类库中。这两个类包可以在Hyperion/Oracle/Informatica等几乎所有非微软系软件中找到,也可以单独下载。

下载地址:

http://www.oracle.com/technetwork/java/javamail/index.html

http://www.oracle.com/technetwork/java/jaf11-139815.html

 

二、 Apache Ant

 

 A. 工具介绍

Apache Ant 是一个自动化工具,由Apache软件基金会所提供,大多用于Java环境中的软件开发。 其可以通过简单配置,来实现各种通用功能,比如通过 SMTP 发送邮件。

 

 B. 环境配置

1) JDK 的路径为:

D:\oracle\product\10.2.0\db_1\jdk

 请确认Java命令路径:

D:\oracle\product\10.2.0\db_1\jdk\bin\java.exe

2) Apache Ant 的路径为:

D:\apache-ant-1.8.1

 请确认Ant命令路径:

D:\apache-ant-1.8.1\bin\ant.bat

3) activation.jar & mail.jar 两个类包应该放置在Apache Ant类库路径下。请确认类库路径:

D:\apache-ant-1.8.1\lib\

4) 解决方案所用的命令、构建文件、配置文件所在目录:

D:\project\email-task

 

 C. 任务文件

1) 构建文件:build.xml

构建文件是Apache Ant运行时最重要的任务文件,里面详细指明了Ant运行时所需要做的详细的任务列表及具体任务内容。

 

<?xml version=”1.0″ encoding=”utf-8″ ?>

<!– Write by Ferrari Huang (redcar.ferrari@qq.com) –>

<!– default 指向默认的起始任务 basedir 指向任务根目录 –>

<project name=”email-project” default=”email-task” basedir=”.”>

<!– file 指定额外的配置文件 –>

<property file=”email.properties” />

<target name=”email-task” description=”ant main task for send mail with files”>

<!– ${}表示变量,变量一般在配置文件中指定,大小写与标点符号敏感。 –>

<mail subject=”${mail.message.subject}”

<!– tolist 是以逗号分隔的收件人邮箱地址 –>

from=”${mail.from.address}” tolist=”${mail.to.addresses}”

<!– 指定邮件服务器地址及SMTP端口 –>

mailhost=”${mail.smtp.host}” mailport=”${mail.smtp.port}”

<!– 如果是匿名发送,就不需要指定用户名密码。 –>

user=”${mail.account.user}” password=”${mail.account.password}”

<!– 指定是否使用SSL –>

ssl=”${mail.smtp.ssl}” >

<!– 邮件内容是文本格式 –>

<message>${mail.message.body}</message>

<attachments>

<!– 根据实际需要增减附件目录和文件,目录和文件都可以使用星号*作为通配符 –>

<fileset dir=”${attachments.dir1}”>

<include name=”${attachments.dir1.file1}”/>

<include name=”${attachments.dir1.file2}”/>

</fileset>

<fileset dir=”${attachments.dir2}”>

<include name=”${attachments.dir2.file1}”/>

</fileset>

</attachments>

</mail>

</target>

</project>

 

2) 变量配置文件:email.properties

变量配置文件是构建文件中所指定,里面详细列出了邮件服务器配置、邮件接收者列表、附件路径。

 

# Write by Ferrari Huang (redcar.ferrari@qq.com)

# Properties of Ant Tasks

 

# STMP服务器地址

mail.smtp.host=smtp.qq.com

# STMP端口

mail.smtp.port=465

# SMTP是否使用SSL

mail.smtp.ssl=true

# 发件人账户

mail.account.user=redcar.ferrari

# 账户密码

mail.account.password=mypassword

# 发件人邮箱地址

mail.from.address=ferrari.huang@longtop.com

# 收件人邮箱地址(以逗号分隔多个地址)

mail.to.addresses=ferrari.huang@longtop.com,redcar.ferrari@qq.com

 

# 邮件的标题

mail.message.subject=Mail sent via Apache Ant email task

# 邮件的文本内容

mail.message.body=Please read the attached files

 

# 根据需要增减附件目录和文件,可以使用星号*作为通配符。注意请使用斜杠/作为系统目录分隔符而不是反斜杠\。

attachments.dir1=D:/project/dir1

attachments.dir1.file1=book1.txt

attachments.dir1.file2=book2.txt

attachments.dir2=D:/project/dir2

attachments.dir2.file1=*.log

 

3) 批处理命令文件:email.cmd

变量配置文件是构建文件中所指定,里面详细列出了邮件服务器配置、邮件接收者列表、附件路径。

 

@echo off

REM ============================================================================

REM Write by Ferrari Huang (redcar.ferrari@qq.com)

REM This batch file is used to send email with several atachement.

REM ============================================================================

 

REM 环境变量,指向JDK目录,java.exe应在其下级目录bin中。

set JAVA_HOME=D:\oracle\product\10.2.0\db_1\jdk

 

REM 环境变量,指向Ant目录,ant.bat应在其下级目录bin中。

set ANT_HOME=D:\apache-ant-1.8.1

 

REM 环境变量,完整的可执行命令目录,以分号;分隔。应包括:%JAVA_HOME%\bin\java.exe & %ANT_HOME%\bin\ant.bat

set path=%JAVA_HOME%\bin;%ANT_HOME%\bin;

 

REM 调用Ant命令,构建文件默认为build.xml,将在运行之后产生日志文件email.log。

ant.bat -l email.log

 

4) 日志文件:email.log

运行结束之后,最后一次的运行结果可以在日志文件中看到。

安装了一个 ActivePerl v5.12.2 环境,写了个 Perl 程序,执行后报错如下:

Use of :unique is deprecated at D:\oracle\product\10.2.0\db_1\perl\5.8.3\lib/MSWin32-x86-multi-thread/Config.pm line 39.

查了一下, 因为安装了 Oracle 10g Database ,所以已经有了 Perl v5.8.3 ,导致冲突。

因为 ActivePerl v5.12.2 模块比较齐全,所以更希望使用 v5.12.2 。于是做了一下简单的设置:

重命名 D:\oracle\product\10.2.0\db_1\perl ,改名为 D:\oracle\product\10.2.0\db_1\perl.bak 。

再次运行程序,一切正常。

星期四
6

一、 项目背景

 

 A. 项目背景

本次项目是一个很小的 BI 项目, 数据源包括几个 Oracle 数据库,数据仓库也建在 Oracle 中,然后抽取到 Essbase 11.1.1.3 ,然后提供给 OBIEE 10 做报表展现。

本次项目的 ETL 工具是 Informatica 8.6.1 ,涉及到的数据源表和数据仓库表也不多,加起来也不过是一百多张表而已。

ETL 的顺序是:数据源表 –> 落地表 –> EDW 表 –> DM 表 –> Essbase 。

 

二、 Session 监控

 

 A. 通常做法

项目在开发测试阶段,每个 Workflow 对应一个 Session ,通过 Monitor 监控运行结果。实际上线时,会在一个 Workflow 中串联或并联多个 Session ,而且一般管理员很少去 Monitor 查看每天的运行情况。这就需要另外加上监控的功能。

通常的做法,是利用每个 Session 配置中的 Components 属性页来实现事后失败(或成功)时做某项操作,比如发送邮件,或者执行某个命令行(来发邮件或做其他动作)。我嫌这样做太麻烦,需要更改每一个 Session ,改动太多,而且下次单个调试时还麻烦。

另外,按照 Informatica 的官方文档,要使用 Email 控件也有一大堆的麻烦,尤其如果要配置 MAPI 的话,需要安装 Microsoft Office Outlook ,还涉及到 License 等问题。

 

 B. 项目做法

我的做法是,直接找 Informatica Repository 的后台表,通过后台表查询 Session 简单运行情况,并且抽取到数据仓库中。然后检查如果有错误的 Session ,发送 Email 给管理员。

至于发送 Email 功能,没有使用 Email 控件,而是使用 Command 控件。具体的实现方式,当然是用了好多年的 Apache Ant自动化工具。

我在每个 Workflow的结尾,都增加四个 Task ,用于监控 Workflow 中的其余之前运行完的 Session 的执行情况。

 

 C. 查询后台表

第一个 Task , s_m_c_etl_session_run 通过查询 Informatica 后台表获得 Session 的执行情况,并保存到 EDW.C_ETL_SESSION_RUN 表中。数据源是一个定制的 Sql Query 。

具体的 SQL 并不标准,但至少在本项目中是正确的。具体如下:

select s.subj_name as folder_name, w.workflow_run_id, w.workflow_name,

t.task_name, to_char(t.start_time, ‘YYYY-MM-DD HH24:MI’) as etl_time,

(t.end_time - t.start_time) * 24 * 60 * 60 as run_seconds,

round((t.end_time - t.start_time) * 24 * 60) as run_minutes,

t.run_err_code, t.run_err_msg

  from pc_rep.opb_task_inst_run t, pc_rep.opb_wflow_run w, pc_rep.opb_subject s

 where t.workflow_run_id = w.workflow_run_id

and w.subject_id = s.subj_id

and w.workflow_run_id = $PMWorkflowRunId

and t.task_name <> ‘$PMSessionName’

 order by t.start_time

其中,$PMWorkflowRunId 和 $PMSessionName 是 Session 内置变量,一个是对应 Workflow 本次运行的实例 ID ,一个是对应本 Session 。这两个参数都会在运行时设值,并传递到 Session 中。

 

 D. 查询出错任务

第二个 Task , s_m_c_etl_error_run 通过查询 EDW.C_ETL_SESSION_RUN 表中本次 Workflow 的ERR_CODE 不为零的记录,保存到文本文件中。 ERR_CODE 不为零,表示对应 Session 出错。

s_m_c_etl_error_run 的 Source Filter 是:

C_ETL_SESSION_RUN.WORKFLOW_RUN_ID = $PMWorkflowRunId and C_ETL_SESSION_RUN.RUN_ERR_CODE <> 0

s_m_c_etl_error_run 的输出文件路径为: $PMWorkflowLogDir\$PMFolderName.$PMWorkflowName.csv 。这其中也用了三个内置变量,实际的路径也是在运行时赋值,比如为:

E:\Informatica\PowerCenter8.6.1\server\infa_shared\WorkflowLogs\EDW.wf0_bw_fact_all.csv 。

 

 E. 判断是否有出错任务

第三个 Task , whether_run_error 是一个判断,判断前一个 Session (s_m_c_etl_error_run) 中的数据源成功条数是否大于零,如果大于零即是有出错任务。

 

 F. 发送邮件

在第四个 Task (mail_error_run) 执行之前,首先判断 whether_run_error 的判断结果,如果判断为TRUE 才执行 mail_error_run ,否则不执行。 mail_error_run 调用 Apache Ant 命令行,发送错误警告邮件给管理员,并将记录错误运行情况的文本文件作为附件。

命令行中命令,又包括了多个内置变量,在运行时赋值。通过命令行命令,这些值又作为 Apache Ant 的动态参数传递过去。

具体的 Apache Ant 命令将在下一章中做简要介绍。

 

 G. 邮件内容

警告邮件的附件中列出出错的Session列表、ETL实际、出错代码、及简单的错误描述。管理员阅读邮件后再进入 Informatica 查看具体情况并解决问题。

 

三、 Apache Ant

 

 A. 工具介绍

Apache Ant 是一个自动化工具,由Apache软件基金会所提供,大多用于Java环境中的软件开发。 其可以通过简单配置,来实现各种通用功能,比如 通过 SMTP 发送邮件。

 

 B. 环境配置

本 Apache Ant 的服务器路径为 E:\apache-ant-1.8.1。需要将这个路径加到服务器的 Path 环境变量中。

除了标准的Apache Ant v1.8.1之外,仅增加了两个外部类库用于发送Email。将这两个 .jar 文件拷贝到目录 E:\apache-ant-1.8.1\lib\ 即可。这两个文件很容易找,甚至在 Informatica 安装目录下就能找到: \Informatica\PowerCenter8.6.1\server\tomcat\webapps\coreservices\WEB-INF\lib\ 。

 

 C. 环境配置

发送 Email 的代码目录在 E:\email-task ,其中包括一个任务主文件(build.xml),一个配置文件(email.properties)和一个日常的日志文件。

 

 D. 主文件

任务主文件 build.xml 中有一个用于发送 Session 错误的任务(mail-error-run),其中仅配置了一个动作:发送Email,包括一个附件。具体内容如下:

<?xml version=”1.0″ encoding=”utf-8″ ?>

<project name=”planning” default=”mail-error-run” basedir=”.”>

<property file=”email.properties” />

<target name=”mail-error-run” description=”ant main task for send warning mail about error run”>

<mail subject=”The ETL workflow was failed (${workflow.name})”

from=”${mail.from.address}” tolist=”${mail.to.addresses}”

mailhost=”${mail.smtp.host}” mailport=”${mail.smtp.port}”

user=”${mail.account.user}” password=”${mail.account.password}”

ssl=”${mail.smtp.ssl}” >

<message>

Please read the attachment for details.

</message>

<attachments>

<fileset dir=”${workflow.log.dir}”>

<include name=”${folder.name}.${workflow.name}.csv”/>

</fileset>

</attachments>

</mail>

</target>

</project>

 

 E. 配置文件

配置文件(email.properties)中。其中配置了邮件服务器的机器名、端口,发送账号的用户名、密码,邮件接收者列表(逗号分隔)。当这些内容有任何变更时,必须修改配置文件。比如,当邮件接受者出现变化时,应修改 mail.to.addresses ,删除不需要的邮件地址,加上新人的邮件地址。

# Write by Ferrari Huang (wxhuangxiaoming@hotmail.com)

# Properties of Ant Tasks

mail.smtp.host=mail.company.com.cn

mail.smtp.port=25

mail.smtp.ssl=false

mail.account.user=etl_pm

mail.account.password=etl_pm

mail.from.address=etl_pm@company.com.cn

mail.to.addresses=zhoux@company.com.cn,dingl@company.com.cn

星期一
18

在项目中,需要通过 Web Service 获取数据,使用到了 SSIS 工具。

其他系统通过的 Web Service 数据源也有正式/测试环境之分,之前没有研究过 SSIS 的迁移,这次研究了一下发现很简单。

SSIS 项目文件在开发阶段可以设置 Web Service 测试数据源,并且部署到测试服务器。迁移过程中,同一 SSIS 项目文件可以直接部署到正式服务器上。仅仅需要通过 SSIS 从 Web Service 获得 WSDL 文件,拷贝到正式服务器的相关位置即可。也就是说,同一 SSIS 项目部署,两个不同环境置放两个不同的 WSDL 文件,即可各自抽取所需的正式/测试数据源。

星期一
11

在项目中,需要通过 EssbaseJavaAPI 导出 Essbase 数据。 EssbaseJavaAPI 的服务器为: D:\oracle\Middleware\EPMSystem11R1\common\EssbaseJavaAPI ,包括 .jar 文件、 JavaDoc 、 samples 代码等都在该目录下,开发时需要用到。另外,更多内容应参考文档 Hyperion Provider Services Administration Guide 。

因研究时间短,没找出 Java 通过嵌入方式连接服务器的方式。理论上嵌入方式会更稳定。

在 Java 通过非嵌入方式运行服务器的时候,一旦数据量交大,就会报网络错误: com.essbase.api.base.EssException: (1290002): Network Error [10061]: Unable To Connect To [server:32769]. The client timed out waiting to connect to the Essbase Server using TCP/IP. Make sure that the client machine has sufficient number of ports available.

根据参考文档,调整了一下配置文件( D:\oracle\Middleware\user_projects\epmsystem1\aps\bin\essbase.properties ),设置了一下以下三个变量,网络错误不再出现。

 

olap.server.netConnectRetry=400

olap.server.netSocketTimeOut=120000

olap.server.netLoopIPAddresses=false

 

因研究时间短,在项目中还有一些属性没有实现导出,比如 UDA 和 SmartList 等。还需要更多研究。

星期一
27

在项目中,因为使用了 SSIS 进行大数据的处理,导致 SQL Server 数据库日志文件超过 10G ,严重影响了数据库的备份。

因为考虑到日志文件几乎派不上用场,所以考虑是否限制日志文件大小,却发现会因为日志文件满溢而导致 SSIS 任务失败。

后来发现,分离数据库,然后删除日志文件,再附加数据库, SQL Server 会发现文件不正确,自动创建一个 500K 左右的新日志文件。

现在开始采用这种方式进行数据库备份,备份时间大大缩短。今后实际效果如何,有待观察。

 

use master

GO

– 获取独占访问权限

ALTER DATABASE mydb SET SINGLE_USER

GO

– 分离数据库

sp_detach_db ‘mydb’

GO

– 附加数据库(在此之前可以删除日志文件,附加时能自动创建新日志文件,从而达到缩小日志文件的目的。)

sp_attach_db ‘mydb’,'D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\mydb.mdf’

GO

 

(后记)实际运行,出现进程停滞在“获取独占访问权限”阶段,怀疑是因为数据库正在使用中而导致。因此,该方案不可行,至少“获取独占访问权限”不可行。

 

星期二
21

一、 安装SMTP虚拟服务器

默认情况下,SMTP 服务不随 IIS 安装。必须使用“控制面板”安装 SMTP 服务。

 

A. 在 IIS 6.0 上安装 SMTP 服务

1. 在“开始”菜单上,单击“控制面板”,双击“添加/删除程序”,然后单击“添加/删除 Windows 组件”。

2. 在“组件”列表中,单击“应用程序服务器”,然后单击“详细信息”。

3. 在“应用程序服务器的子组件”列表中,单击“Internet 信息服务 (IIS)”,然后单击“详细信息”。

4. 在“Internet 信息服务 (IIS) 的子组件”列表中,选中“SMTP 服务”复选框,然后单击“确定”。

5. 单击“下一步”。如果系统提示您插入 Windows CD 或输入网络安装路径,请按照说明操作。

6. 单击“完成”。

 

二、 配置 SMTP 虚拟服务器

安装 SMTP 服务将在 IIS 管理器中创建一个新节点。若要配置 SMTP 虚拟服务器,必须启动 IIS 管理器。

 

从管理服务控制台启动 IIS 管理器

1. 在“开始”菜单上,单击“控制面板”。

2. 在“控制面板”窗口中单击“管理工具”。

3. 在“管理工具”窗口中单击“Internet 信息服务”。

 

修改允许中继计算机

1. 默认 SMTP 虚拟服务器的默认设置中,允许匿名发送邮件,但对提交发送邮件申请的计算机(中继计算机)有限制。

2. 在“默认 SMTP 虚拟服务器”上右键,单击“属性”。

3. 切换到“访问”子页,单击“中继”(”Relay”)。

4. 默认选择是“仅以下列表”(”Only the list below”),为严格控制允许发送申请的来源,应保留该设置。

5. 单击“添加”,选择“单台计算机”,填入允许发送Email的计算机IP(如本机为127.0.0.1),单击“确定”完成中继计算机的添加。

6. 若要允许多台中继计算机,继续单击“添加”。

 

启用日志

1. 默认 SMTP 虚拟服务器的默认设置中,未启用日志。

2. 在“默认 SMTP 虚拟服务器”上右键,单击“属性”。

3. 在“常规”子页,勾选“启用日志记录”。

4. 选择“Microsoft IIS 日志文件格式”,以获得较好的日志可读性。

5. 日志文件放置的地址默认是C:\WINDOWS\System32\LogFiles,“默认 SMTP 虚拟服务器”的SMTP日志的默认子文件夹为SMTPSVC1。

 

三、 发送邮件

以上配置方式允许匿名发送邮件。

 

匿名发送邮件

1. 邮件服务器地址:IIS所在服务器IP或机器名

2. SMTP端口:默认 25

3. 身份验证:不需验证

4. 必须填写发送邮件地址和接收邮件地址

5. 允许HTML格式内容,允许发送附件。

星期天
19

在项目中,客户系统通过 Web Service 提供数据,返回类型是 DataTable 。我在项目中需要找到最合适的方式保存到目标数据库中(源表与目标表完全同结构)。开始希望提供 SSIS 常规控件来做,但是发现实现不了。转为使用 C# 脚本配合来做,但是一开始写的脚本比较差,效率太低。后来改用 SqlBulkCopy 快速大批量导入数据,大大提高了效率。

实际项目中,还有 Web Service 任务的部分,以下代码为归纳出的纯 C# 实现方式。

 

[WebMethod]

public DataTable GetHotelKind()

{

}

 

public int QueryWebService()

{

string date = “20090101″;

string url = “http://localhost/GetInfo.asmx/GetHotelKind?date=” + date;

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);

 

DataTable table = new DataTable();

using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.UTF8))

{

table.ReadXml(reader);

}

 

string sql;

using (SqlConnection conn = new SqlConnection(CONNECTION_STRING))

{

conn.Open();

sql = “truncate table HotelKind”;

SqlCommand cmd = new SqlCommand(sql, conn);

cmd.ExecuteNonQuery();

 

SqlBulkCopy bulkcopy = new SqlBulkCopy(conn);

bulkcopy.BatchSize = 5000;

bulkcopy.DestinationTableName = “HotelKind”;

bulkcopy.WriteToServer(table);

 

sql = “select count(1) from HotelKind”;

cmd = new SqlCommand(sql, conn);

SqlDataReader reader = cmd.ExecuteReader();

reader.Read();

return reader.GetInt32(0);

}

}

使用 PIVOT 和 UNPIVOT : 可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表。PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。UNPIVOT 与 PIVOT 执行相反的操作,将表值表达式的列转换为列值。

PIVOT 和 UNPIVOT 关系运算符是 SQL Server 2005 提供的新增功能。在 Oracle 11g 中也同样增加了该项新特性。

惭愧得很,在收到网友的提示之前,我对 PIVOT 和 UNPIVOT 一无所知。为了取12个月数据居然做了12条 SQL 的 UNION ALL 。知道了之后,如获至宝。

SELECT d.dept_name AS dim_dept,b.dim_account,b.dim_year,

                                       b.dim_period, SUM(b.date_value) AS date_value

  FROM dept_budget UNPIVOT

       (data_value FOR dim_period IN (Jan, Feb, Mar, Apr, May, Jun,

                                       Jul, Aug, Sep, Oct, Nov, Dec)) b

 INNER JOIN dept_dim ON b.dim_dept = d.dept_id

 GROUP BY d.dept_name, b.dim_account, b.dim_year, b.dim_period

星期一
28

一. 文件目录结构:

root

|__build.xml——————————————————————ant 任务文件

|__sdks—————————————————————————flex sdk 目录

|__3.5.0——————————————————————flex sdk (version 3.5.0)

|__src

|__main

|__flex————————————————————flex 源文件目录

|__main.mxml —————————————flex 主文件

|__libs————————————————————————— 程序中所使用到的类库目录

|__target——————————————————————— 编译结果输出目录

二. build.xml文件内容:

<?xml version=”1.0″?>

<project name=”Flex Ant Tasks” default=”main” basedir=”.”>

<property name=”project.version” value=”0.1.0-SNAPSHOT” />

<property name=”flex.version” value=”3.5.0″ />

<!– pplication mxml –>

<property name=”app.mxml” value=”main” />

<!– html title for application –>

<property name=”app.title” value=”Flex Ant Sample” />

<!– flex sdk location –>

<property name=”FLEX_HOME” value=”${basedir}/sdks/${flex.version}” />

<!– flex ant tasks –>

<property name=”flex.tasks” value=”${FLEX_HOME}/ant/lib/flexTasks.jar” />

<!– flex source root –>

<property name=”src.root” value=”${basedir}/src/main/actionscript” />

<!– third party swc files path –>

<property name=”lib.path” value=”${basedir}/libs” />

<!– compile target path –>

<property name=”target.path” value=”${basedir}/target/${project.version}” />

<!– define flex ant tasks –>

<taskdef resource=”flexTasks.tasks” classpath=”${flex.tasks}” />

<!– main ant task –>

<target name=”main” depends=”clean,compile,wrapper” />

<!– compile task –>

<target name=”compile”>

<!– mxmlc task –>

<mxmlc actionscript-file-encoding=”UTF-8″

file=”${src.root}/${app.mxml}.mxml”

output=”${target.path}/${app.mxml}.swf”

keep-generated-actionscript=”false”

incremental=”true”>

<!– refer to flex-config.xml –>

<load-config filename=”${FLEX_HOME}/frameworks/flex-config.xml” />

<!– refer to flex sdk framesworks –>

<source-path path-element=”${FLEX_HOME}/frameworks” />

<!– refer to flex source root –>

<compiler.source-path path-element=”${src.root}” />

<!– refer to flex sdk libs –>

<compiler.library-path dir=”${FLEX_HOME}/frameworks” append=”true”>

<include name=”libs” />

<include name=”../bundles/{locale}” />

</compiler.library-path>

<!– refer to third party swc files –>

<compiler.include-libraries dir=”${lib.path}” append=”true”>

<include name=”*.swc” />

</compiler.include-libraries>

</mxmlc>

<!– delete cache file –>

<delete>

<fileset dir=”${target.path}” includes=”*.cache” />

</delete>

</target>

<!– html wrapper task –>

<target name=”wrapper”>

<html-wrapper title=”${app.title}”

file=”${app.mxml}.html”

swf=”${app.mxml}”

output=”${target.path}/”

height=”100%”

width=”100%”

bgcolor=”white”

version-major=”9″

version-minor=”0″

version-revision=”0″

history=”true”

template=”express-installation” />

</target>

<!– delete target path –>

<target name=”clean”>

<delete dir=”${target.path}” />

</target>

</project>