Рубрика: Flex

Package organization

Организация кода в пакеты

Словарь

Рефакторинг - Классическая книга описывающая практики рефакторинга - http://www.ozon.ru/context/detail/id/1308678/
DSL - Domain-specific language

Введение

Пакеты это механизм для организации кода и разрешения конфликта уникальности наименования классов. Это техническое определение, но по какому принципу создавать наименования? Какими критериями руководствоваться? И зачем вообще об этом задумываться?
К сожалению этот вопрос слабо освещен в классической литературе. В данной статье я хочу поделиться своим опытом и некоторыми исследованиями по данному вопросу. Первая часть статьи это моя попытка выделить общие принципы. В частности много идей я подчеркнул из презентации Juergen Hoeller, http://www.infoq.com/presentations/code-organization-large-project. Вторая часть статьи - описание вымышленного flex проекта и пошаговое развитие его структуры на основе сформулированных принципов и моего личного опыта.

Общие принципы

Можно сформулировать следующие архитектурные принципы:

      Избегать циклических зависимостей;
      Избегать дублирования;
      Формировать модули;
      Стремиться создавать слабо связанные модули;
      Выбирать модули на основе логической, концептуальной организации (домена)

Далее о каждом их них более подробно:

Избегать циклических зависимостей между пакетами

картинка

Циклическая зависимость это когда два пакета ссылаются друг на друга. Обычно такая зависимость не планируется и появляется в последствии. Часто это может быть признаком ухудшения общего состояния кода. Создание пакетов - динамический процесс. Со временем приложение меняется, появляется новая функциональность, старая переосмысливается. Возможно вам придется разделить пакеты по разным приложениям(библиотекам) и компилировать по отдельности. Циклическая зависимость усложняет понимание и развитие кода. Не дает его повторно использовать.

Избегать дублирования

Часто альтернативой циклической зависимости является дублирование кода. Но такой код уже плохо пахнет. Дублирование загромождает код и затрудняет его модификацию. Попробуйте переосмыслить местоположение нового кода и не прятать его глубоко в иерархии.

Формировать модули

Модуль это концептуальная сущность содержащая один или несколько дочерних пакетов. Модуль определяет границы для используемых в нем пакетов.

Стремиться создавать слабо связанные модули

картинка
Слабая связность модулей также обеспечивает более понятный код и облегчает повторное использование.

Выбирать модули на основе логической, концептуальной организации (домена)

Часто модули разделяют на основе типов, например:
картинка
или на основе уровней:
картинка
Данная организация имеет право на существование, но она искусственная, то есть не следует из природы вещей. На мой взгляд, лучшим решением является разбиение на основе домена предметной области. Такое разделение ортогонально разбиению на основе типов или слоев, и развивается более естественно и имеет прозрачные границы.
картинка

Зачем об этом заботиться?

Правильная организация пакетов и модулей позволит:
- создать устойчивый внешний API для поддержки обратной совместимости;
- уменьшить время на понимание кода;
- упростить тестирование;
- облегчить повторное использование;
- уменьшить время компиляции, что немаловажно для большого приложения;
- привнести в работу программиста творчество.

Пример и несколько практических советов

В последнее время я часто встречаю в flex приложении структуру пакетов следуещего вида:
vo
view
model
control
commands
business
events
Такое разделение на пакеты пришло к нам из фреймворка Cairngorm, где, видимо его применение оправдано. Но оно встречается и в приложениях, где Cairngorm не используется. Как показывает моя практика, такое разделение плохо развивается при разрастании приложения, пакеты получаются сильно связанные и их практически невозможно использовать повторно в другом приложении.
Я использую разбиение по логике или функциональности. Попробую привести пример.

Рассмотрим приложение AdminPanel

Здесь будет показан сам принцип создания пакетов. Не надо воспринимать получившуюся структуру как эталон, в реальном приложение много дополнительных деталей и специфики.

Начальная структура

rootpackage = com.agakhov.examples.adminpanel
rootpackage.ApplicationView.mxml // определяется размещение всех компонентов приложения
rootpackage.MainDataModel.as // модель данных всего приложения
rootpackage.MainEventMap.xml // сущность из фреймворка mate, её можно заменить обычным классом контроллера
rootpackage.AdminApplucationEvent.as // событие уровня приложения, например ApplicationStart
defaultpackage.Main.xml //создает и инициализирует основные компоненты)

То, что я делал до сих пор, относилось ко всему приложению, поэтому я не выделял никаких специализированных пакетов. Приложение запускается показывает пустое окно и закрывается. Но уже работает.

Login

Допустим, что первая по приоритету задача это аутентификация, для неё я создаю пакет login, собирающий все что связано с этой задачей:
rootpackage.login.LoginView
rootpackage.login.LoginEvent
rootpackage.login.LoginLocalEventMap // содержит методы обращения к сервису
rootpackage.login.LoginModel

Теперь после загрузки наше приложение открывает форму авторизации LoginView и после её заполнения отправляет запрос на сервер. В случае успешной аутентификация и авторизации, посылается сообщение основному приложению и закрывается LoginView.

Registration

Возможно, данного пользователя нет в системе и он захочет зарегистрироваться. Для этого мы создаем пакет registration
rootpackage.registration.RegistrationView
rootpackage.registration.RegistrationEvent // события регистрации
rootpackage.registration.RegistrationlEventMap // содержит методы обращения к сервису регистрации
rootpackage.registration.RegistrationModel // данные о регистрации

Теперь пользователь может открыть окно регистрации, заполнить поля. Если все в порядке, информация отправляется на сервер.

В случае удовлетворительного ответа от сервера, RegistrationView закрывается, основное приложение получает соответствующее сообщение. Дальнейшее развитие этих пакетов зависит от сложности процесса регистрации и авторизации, например регистрация может использовать OpenId, капчу, автозаполнение и т.п. Если процессы многообразны, то возможно создать для их обработки отдельную EventMap. Некоторые функции попросятся в собственный модуль. Но сосредоточимся пока на доменах registration и login
картинка

Переход к высокоуровневому домену

Сейчас явно напрашивается желание собрать регистрацию и логи в общий пакет (модуль).
Я придумал наименование accessmanagment.
rootpackage.accessmanagment.AccessManagementModel.as
rootpackage.accessmanagment.AccessManagementLocalEventMap.xml
rootpackage.accessmanagment.AccessManagmentEvent
rootpackage.accessmanagment.login.LoginView
rootpackage.accessmanagment.login.LoginEvent
rootpackage.accessmanagment.login.LoginLocalEventMap // содержит методы обращения к сервису
rootpackage.accessmanagment.login.LoginModel
rootpackage.accessmanagment.registration
rootpackage.accessmanagment.registration.RegistrationView
rootpackage.accessmanagment.registration.RegistrationEvent
rootpackage.accessmanagment.registration.RegistrationlEventMap
rootpackage.accessmanagment.registration.RegistrationModel

Ортогональный домен

Думаю, идея создания пакетов на основании домена понятна, но напрашивается вопрос, что делать, если один и тот же класс необходимо использовать в нескольких модулях?
Для задач ортогональных домену предметной области я обычно завожу папку common на соответствующем уровне иерархии. Например мне необходимо выделить базовый класс для всех mate моделей или общего предка для всех модальных окон:

rootpackage.ApplicationView.mxml
rootpackage.MainDataModel.as
rootpackage.MainEventMap.xml
rootpackage.AdminApplucationEvent.as
defaultpackage.Main.xml
rootpackage.common
rootpackage.common.model.AbstractMateModel.as
rootpackage.common.view.ModalView.as
rootpackage.accessmanagment.*
rootpackage.accessmanagment.login.*
rootpackage.accessmanagment.registration.*

картинка
Для пакета common основным доменом будет именно ортогональная задача. Далее сommon может быть вынесен в самостоятельный проект используемый различными приложениями. Собственно, это и есть его продвижение по иерархии. Если мы выделим common на уровне accessmanagment, он будет использоваться задачами регистрация и аутентификация. Далее он может полностью или частично двигаться вверх в common для всего приложения и еще выше для нескольких приложений. Ну и наконец превратиться в публичный API.

Резюме

Основную идею которую я хотел передать - создание пакетов на основе домена предметной области. Такая техника оправдывает себя в моей практике. Хорошо работает в больших проектах. Для маленьких проектов я бы рекомендовал не создавать пакетов совсем. Зачем два события отделять в отдельный пакет? Как только приложение начнет расти, появятся пакеты предметной области это позволит всегда работать с маленьким приложением.

Ссылки

Всем заинтересовавшимся вопросом рекомендую к ознакомлению видео презентацию Juergen Hoeller, одного из основателей Spring Framework http://www.infoq.com/presentations/code-organization-large-projects и (или) её текстовые пересказы http://mikenereson.blogspot.com/2007/06/spring-on-code-organization-for-large.html,
http://www.kimchy.org/spring-one-code-organization/
Немного странный источник, но идеи примерно те же http://docstore.mik.ua/orelly/oracle/advprog/ch02_01.htm

Постоянная ссылка 2009-08-14 16:51:40, от agahov Email , 6132 слов, Рубрики: Flex, AS3 , 3 комментариев »

Flex mojos 3.1 released

Релиз

Вышла новая версия Flex Mojos, теперь разработка flexmojos проходит под крышой
sonatype.org, и у алмаза появилась огранка)).
В извесную книгу о maven от sonatype добавленна глава про работу с flexmojos

Что изменилось?

Из полезных дополнений хочу обратить внимание на archetypes:

  • flexmojos-archetypes-library проект swc библиотеки
  • flexmojos-archetypes-application
  • простой swf проект
  • flexmojos-archetypes-modular-webapp многомодульный проект, состоит из swc, swf и war

archetypes - это maven комманда, которая создает проект с нуля. Для её запуска необходим установленный maven.
Выполните следующую комманду в командной строке (имя вашего пакета, верисю и артифакт id придется ввести в режиме диалога):

XML:

mvn archetype:generate \
      -DarchetypeRepository=http://repository.sonatype.org/content/groups/public \
      -DarchetypeGroupId=org.sonatype.flexmojos \
      -DarchetypeArtifactId=flexmojos-archetypes-library \
      -DarchetypeVersion=3.1.0

Комментарий
что бы проект собирался необходимо определить sonatype репозиторий в ~\.m2\settings.xml

XML:

<repositories>    
  <!−− ... −−>  
  
  <repository>  
    <id>flex-mojos-repository</id>  
      <url>http://repository.sonatype.org/content/groups/public</url>  
      <releases>  
        <enabled>true</enabled>  
      </releases>  
      <snapshots>  
        <enabled>true</enabled>  
      </snapshots>  
  </repository>
 
<pluginRepositories>  
  
  <!−− ... −−>  
  
  <pluginRepository>  
    <id>flex-mojos-repository</id>  
    <url>http://repository.sonatype.org/content/groups/public</url>  
    <releases>  
      <enabled>true</enabled>  
    </releases>  
    <snapshots>  
      <enabled>true</enabled>  
    </snapshots>  
  </pluginRepository>  
  
  <!−− ... −−>  
  
</pluginRepositories>

после этого можно запускать mvn install.

Для пользователей mac, что бы запускались тесты, необходимо добавить путь к flash player в PATH.

Code:

export PATH="set your path here/Adobe Flex Builder 3 Plug-in/Player/mac/10/mac/Flash Player.app/Contents/MacOS":$PATH

и добавить в pom.xml следующие сторики:

XML:

...
<configuration>
     <flashPlayerCommand>Flash Player</flashPlayerCommand>
</configuration>
...

И на десерт, команда:

Code:

mvn flexmojos:flexbuilder

создает flexbuilder проект. Единственно есть небольшой баг.
Придется поправить в FlexBuilder откройте
Project->Properties->Flex Compiler и исправьте в additional compiler arguments:
-localeen_US на -locale en_US

Тем кто переходит с версии flexmojos 2.x

Изменился репозиторий на http://repository.sonatype.org/content/groups/public
Изменился пакет и наименование flexmojos:

XML:

<groupId>info.flex-mojos</groupId>
<artifactId>flex-compiler-mojo</artifactId>

теперь будет:

XML:

<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>

вместо специализированных плагинов типа:

XML:

<groupId>info.flex-mojos</groupId>
<artifactId>html-wrapper-mojo</artifactId>

теперь используются соответствующие goals, соответственно
mvn flexmojos:wrapper

Пакеты зависимостей для тестирования тоже поменялись:

XML:

<dependency>
<groupId>info.flex-mojos</groupId>
<artifactId>testing-support</artifactId>
<version>${flex-mojos.version}</version>
<type>swc</type>
<scope>test</scope>
</dependency>

теперь:

XML:

<dependency>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-unittest-support</artifactId>
<version>${flex-mojos.version}</version>
<type>swc</type>
<scope>test</scope>
</dependency>

Резюме

В целом изменения меня очень радуют, всё стало проще и логичней, в добавок sonatype обещают интеграцию с m2e в версии 0.9.8.

Первоисточники

flexmojos - blog
советы по переходу с flexmojos 2.x
страница проекта flexmojos
глава из книги о maven, по работе с flexmojos

p/s

Версия новая и интересная буду очень рад если поделитесь опытом и замечаниями по работе с ней.

Постоянная ссылка 2009-04-14 04:15:08, от agahov Email , 1495 слов, Рубрики: Flex , 2 комментариев »

Flex-Mojos. Пример сборки flex modules.

Предисловие

Flex модули на мой взгляд очень интересная и многообразная тема. Кроме разделения функциональности приложения, их можно использовать для загрузки внешних стилей и ресурсов. Если есть задача динамического изменения внешнего вида и языка или уменьшение размера основного приложения.

Введение

В данной статье я расскажу как собирать приложение которое использует flex modules.
Проект так же будет использовать библиотеки и уменьшать размер flex модулей. Для этого мы не будем включать в модуль код, который уже используется в основном приложении. Итак приступим.

Структура проекта

Данная структура соответствует принципу один maven модуль один артефакт. Следовательно flex модуль представлен ввиде отдельного maven модуля.

flexModulesProject/
flexModulesProject/pom.xml - основной pom, собирающий весь проект
//загрузчик модульного приложения.
flexModulesProject/flexClient/… - основное flex приложение

flexModulesProject/flexModuleRed/… - flex модуль

flexModulesProject/flex/pom.xml - корневой pom для flex приложение.
flexModulesProject/flexCoreLib/… - flex библиотека которая используется в проекте.

Разбор конфигурационных файлов проекта

на родительский pom проекта, pom библиотеки и корневой pom для flex проектов использование модуля ни как не повлияло. Более подробное описание их структуры можно посмотреть здесь.

pom для flexClient

XML:

<?xml version="1.0"?>
<project>
     <parent>
   <groupId>com.mydomain.mypackage</groupId>
         <artifactId>my-flex-super-pom</artifactId>
         <version>1.0</version>
     </parent>
  
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.mydomain.mypackage</groupId>
      <artifactId>flex-client</artifactId>
      <packaging>swf</packaging>
      <name>flex client</name>
      <version>1.0</version>
      
      <build>
        <plugins>
            <plugin>
            <groupId>info.rvin.mojo</groupId>
            <artifactId>flex-compiler-mojo</artifactId>
            <configuration>
                <debug>true</debug>
                <sourceFile>flexClient.mxml</sourceFile>
                <linkReport>true</linkReport>
            </configuration>
      </plugin>
        </plugins>
    </build>
      
      
        <dependencies>
               <dependency>
                  <groupId>com.mydomain.mypackage</groupId>
                  <artifactId>flex-core-library</artifactId>
                  <version>1.0</version>
                  <type>swc</type>
                  <scope>internal</scope>
               </dependency>
        </dependencies>
</project>

Здесь существенна одна дирректива:

XML:

<linkReport>true</linkReport>

данная строчка создает в maven репозитории xml файл с перечнем всех классов, которые включаются в данный swf. Этот перечень будет использоваться при копмиляции flex модуля.

pom для flexModuleRed

XML:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
     <parent>
  <groupId>com.mydomain.mypackage</groupId>
        <artifactId>my-flex-super-pom</artifactId>
        <version>1.0</version>
      </parent>
    <groupId>com.mydomain.mypackage</groupId>
  <artifactId>flexModuleRed</artifactId>
  <packaging>swf</packaging>
  <name>flex module red</name>
  <version>1.0</version>
    <build>
        <plugins>
            <plugin>
            <groupId>info.rvin.mojo</groupId>
            <artifactId>flex-compiler-mojo</artifactId>
            <configuration>
                <debug>true</debug>                
                <sourceFile>FlexModuleRed.mxml</sourceFile>
                <loadExterns>
          <MavenArtifact>
            <groupId>com.mydomain.mypackage</groupId>
            <artifactId>flex-client</artifactId>
            <version>1.0</version>
          </MavenArtifact>
                </loadExterns>
 
 
 
            </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
          <dependency>
              <groupId>com.mydomain.mypackage</groupId>
        <artifactId>flex-core-library</artifactId>
              <version>1.0</version>
              <type>swc</type>
              <scope>external</scope>
          </dependency>
     </dependencies>
</project>

следующий код:

Code:

<loadExterns>
  <MavenArtifact>
      <groupId>com.mydomain.mypackage</groupId>
      <artifactId>flex-client</artifactId>
      <version>1.0</version>
   </MavenArtifact>
</loadExterns>

исключает классы которые включены в flex-client.

здесь:

Code:

<dependency>
  <groupId>com.mydomain.mypackage</groupId>
  <artifactId>flex-core-library</artifactId>
  <version>1.0</version>
  <type>swc</type>
  <scope>external</scope>
</dependency>

важно включение библиотеки со scope external.

Еще одно замечание, имя flex модуля не должно использовать дефис, в моём проекте это вызвало необъяснимый глюк.

Сборока проекта.

Для сборки проекта необходимо в корневой библиотеке проекта запустить команду mvn install

Развертывание проекта.

Строго говоря, в обязанности maven эта задача не входит. После того как проект будет собран, нужно поместить flexModuleRed.swf в одну папку с flexClient.swf.

Исходники

Исходники можно взять отсюда

Постоянная ссылка 2008-08-13 19:49:50, от agahov Email , 565 слов, Рубрики: Flex, maven , 7 комментариев »

Flex-Mojos. Пример сборки модульного проекта.

Глоссарий

flex module - swf, которая может быть загружена или выгружена flex приложением. Она не может быть запущена независимо. Несколько приложений могут использовать один и тотже модуль.(как собирать flex модули я опишу в следующей статье)
maven module - логическая часть вашего проекта, например клиентские программы, библиотеки, серверные модули, модули конфигурации и т.п.

Введение

Рассмотрим сборку проекта состоящего их нескольких maven модулей. Для построения такого проекта нам потребуется, создать иерархическую структуру директорий, для каждого модуля своя директория, в каждой директории будет находиться исходный код модуля и роm.xml, который его собирает. В корневой директории будет находится родительский pom для всего проекта.

Структура проекта

картинка

Проект состоит из двух модулей:
корень проекта:
multyModulesProject/pom.xml - родительский роm.xml
flex библиотека:
multyModulesProject/flexCoreLibrary/pom.xml;
multyModulesProject/flexCoreLibrary/…;
flex приложение:
multyModulesProject/flexClient/pom.xml;
multyModulesProject/flexClient/…;

Наследование от flex-super-pom

Это достаточно тонкий момент. Возможны следующий решения:

  • Унаследовать родительский pom от flex-super-pom. При данном решении возникает вопрос, что делать с модулями которые не имеют отношения к flex.
  • Прописать все необходимые свойства непосредственно в дочерние модули. Приводит к излишнему дублированию кода.
  • Создать ещё один уровень иерархии. С модулями flex и java например. В модуле flex будет находиться my-flex-super-pom. Наследуется от родительского pom всего проекта и включает все необходимые параметры из flex-super-pom. Все maven модули собирающие flex, наследуются от my-flex-super-pom и помещаются в директорию flex. Недостаток данного метода в появлении ещё одного уровня иерархии.
  • И последний вариант, который я использую: Появляется модуль flex и my-flex-super-pom, как в предыдущем решении, но не создается иерархия. Все модули помещаются в корневую директорию. Модули собирающие flex артифакты наследуются от my-flex-super-pom. Сложность здесь в некоторой путанице с наследованием. Она не всегда совпадает с директориями, в которых находятся модули.

В итоге к нашему проекту добавился ешё один модуль flex.
multyModulesProject/flex/pom.xml; - по умолчанию полностью повторяет структуру flex-super-pom, но наследуется от родительского pom.

Родительский pom проекта

Родительский pom.xml нашего проекта может выглядеть следующим образом:

XML:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mydomain.mypackage</groupId>
    <artifactId>myProjectArtifactId</artifactId>
    <name>myProjectName</name>
    <packaging>pom</packaging>
    <version>1.0</version>
    <url>http://maven.apache.org</url>
    <modules>
        <module>flex</module>
        <module>flexCoreLibrary</module>
        <module>flexClient</module>
    </modules>
            <repositories>
                  <repository>
                          <id>flex-mojos-repository</id>
                          <url>http://svn.sonatype.org/flexmojos/repository/</url>
                          <releases>
                                  <enabled>true</enabled>
                          </releases>
                  </repository>
      </repositories>
  
      <pluginRepositories>
 
          <pluginRepository>
            <id>flex-mojos-repository</id>
            <url>http://svn.sonatype.org/flexmojos/repository/</url>
            <releases>
              <enabled>true</enabled>
            </releases>
            <snapshots>
              <enabled>false</enabled>
            </snapshots>
          </pluginRepository>
        </pluginRepositories>
</project>

На что стоит обратить внимание:

XML:

<packaging>pom</packaging>

определяет тип собираемого артефакта, в данном случае pom.xml, оперирует другими pom.xml. Тип родительского модуля логический, обозначается “pom".

XML:

...
  <modules>
        <module>flex</module>
        <module>flexCoreLibrary</module>
        <module>flexClient</module>
        
  </modules>
...

здесь перечислены модули проекта, наименования должны совпадать с наименованием директорий.

XML:

...
<repositories>
...

тег repositories, выноситься в родительский pom.xml, так как maven поддерживает наследование, то данное свойство будет доступно в дочерних модулях.

Замечу что если у вас несколько проектов, то лучше его вынести в файл конфигурации maven.
под winXP, он находиться в: “C:\Documents and Settings\username\.m2\settings.xml", в других OS в той-же по смыслу директории.

my-flex-super-pom

Находиться в дирректории: multyModulesProject/flex
Отличается от flex-super-pom, добавлением кода определяющего родителя:

XML:

...
     <parent>
       <groupId>com.mydomain.mypackage</groupId>
       <artifactId>myProjectArtifactId</artifactId>
       <version>1.0</version>
    </parent>
...

и другим именем:

XML:

...
    <groupId>com.mydomain.mypackage</groupId>
    <artifactId>my-flex-super-pom</artifactId>
    <version>1.0</version>
    <name>parent pom for building modules with flex</name>
    <packaging>pom</packaging>
...

flex-core-library

Находится в директории: multyModulesProject/flexCoreLibrary:

XML:

<?xml version="1.0"?>
  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 href="http://maven.apache.org/maven-v4_0_0.xsd">">http://maven.apache.org/maven-v4_0_0.xsd">
      <parent>
        <groupId>com.mydomain.mypackage</groupId>
              <artifactId>my-flex-super-pom</artifactId>
              <version>1.0</version>
      </parent>
  
      <modelVersion>4.0.0</modelVersion>
  
      <groupId>com.mydomain.mypackage</groupId>
      <artifactId>flex-core-library</artifactId>
      <packaging>swc</packaging>
      <name>flex-core-library</name>
      <version>1.0</version>
 
  </project>

Тег parent

устанавливает родительский pom. Теперь всё что определено в my-flex-super-pom будет доступно в данном проекте.

flex-client

Находится в директории: multyModulesProject/flexClient

XML:

<?xml version="1.0"?>
  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 href="http://maven.apache.org/maven-v4_0_0.xsd">">http://maven.apache.org/maven-v4_0_0.xsd">
      <parent>
        <groupId>com.mydomain.mypackage</groupId>
              <artifactId>my-flex-super-pom</artifactId>
              <version>1.0</version>
      </parent>
  
      <modelVersion>4.0.0</modelVersion>
  
      <groupId>com.mydomain.mypackage</groupId>
      <artifactId>flex-client</artifactId>
      <packaging>swf</packaging>
      <name>flex client</name>
      <version>1.0</version>
 
            <dependencies>
               <dependency>
                 <groupId>com.mydomain.mypackage</groupId>
            <artifactId>flex-core-library</artifactId>
                  <version>1.0</version>
                  <type>swc</type>
                  <scope>internal</scope>
               </dependency>
            </dependencies>
  </project>

Тег parent

устанавливает родительский pom. Теперь всё что определено в my-flex-super-pom будет доступно в данном проекте.

Тег dependency

определяет зависимость flex-client от flex-core-library

Исходники

исходный код проект

Постоянная ссылка 2008-07-21 22:21:20, от agahov Email , 2027 слов, Рубрики: Flex, maven , 2 комментариев »

Flex-Mojos, Управление зависимостями.

Введение

В данной статье будет рассмотрена тема управление зависимостями при сборки flex приложения с помощью maven.
содержание предыдущих серий:
Пара общих слов о maven
Сборка простого flex приложения с помощью Flex Mojos;
Генерация html wrapper c помощью flex-mojos;

Что такое maven зависимости?

Допустим мы хотим используем в своём проекте, внешнюю swc. В Flex Builder необходимо её подключить. В maven это решается с помощью указания зависимости от maven артефакта. Этот артефакт представляет собой ссылку на swc в репозитории maven.
Пример:

Code:

<project>
...
<dependencies>
        <dependency>
            <groupId>com.mydomain.mypackage</groupId>
            <artifactId>mylibrary</artifactId>
            <version>1.0</version>
            <type>swc</type>
            <scope>external</scope>
        </dependency>
        ...
<dependencies>
...
</project>

Теги: groupId, artifactId, version, type - определяют путь к артефакту в maven repository,
Тег scope - определяет, как будет использоваться артефакт и может принимать следующие значения:
external - код swc, используется только для компиляции.
internal - код swc, полностью включается в итоговый проект.
merged - включается только та часть кода swc , которая используется в вашем проекте. Данное значение используется по умолчанию.
rsl - будет загружать swf, как rsl
caching - тоже что и rsl, но только для adobe библиотек swz, которые могут кэшироваться fp.
test - для компиляции тестов.

Я выделил жирным значения scope и тип артефакта с которым используется scope.

Как поместить артефакт в репозиторий?

Собственные библиотеки

Если вы собираете библиотеку с помощью maven, то она попадает в репозиторий после выполнения команды >mvn install.
После этого её можно использовать в любом вашем проекте указав зависимость.

Внешние библиотеки

В данный момент maven не слишком распространён в среде flex разработки. Поэтому общие библиотеки которые могут вам понадобиться(as3corelib, caingorm и т.д.) обычное не лежат в публичных репозиториях. Следовательно вам необходимо выложить их в свой локальный репозиторий. Для этого существует специальная команда maven:

Code:

mvn install:install-file -Dfile=  -DgroupId= \ -DartifactId= -Dversion= -Dpackaging=

Дополнения

Информациию о scopes и dependency можно также посмотреть на blog.flex-mojos;

Постоянная ссылка 2008-07-10 05:17:00, от agahov Email , 1388 слов, Рубрики: Flex, maven , Оставить комментарий »

Генерация html wrapper c помощью flex-mojos

Введение

Получить общее представление и посмотреть простой пример, c помощью flex mojos, можно здесь.

Также возможно ознакомиться с первоисточником Html Wrapper Mojo от Marvin Froeder’s, создателя flex mojos.

Знакомство с html-wrapper-mojo

Для того что бы сгенерить html wrapper для swf, достаточно в pom.xml
добавить mojo html-wrapper-mojo.

XML:

...
  <plugins>
            <plugin>
              <groupId>info.flex-mojos</groupId>
              <artifactId>html-wrapper-mojo</artifactId>
              <executions>
                <execution>
                  <goals>
                    <goal>wrapper</goal>
                  </goals>
                </execution>
              </executions>
               <configuration>
                  <templateURI>embed:client-side-detection</templateURI>
                  <parameters>
                      <swf>${build.finalName}</swf>
                      <width>200</width>
                      <height>200</height>
                  </parameters>
               </configuration>  
            </plugin>
        </plugins>
...

Конфигурация html-wrapper-mojo

тег templateURI

определяет один из варинтов шаблона от Adobe:
embed:client-side-detection
embed:client-side-detection-with-history (default)
embed:express-installation
embed:express-installation-with-history
embed:no-player-detection
embed:no-player-detection-with-history

или

URI на ваш собственный шаблон, например:"file:///etc/hosts". При этом файл с вашим шаблоном должен содержать index.template.html и быть в формате zip.

тег parameters

позволяет установить значения всем стандартным свойствам шаблона
title
version_major - требуемая версия fp, по умолчанию 9;
version_minor - требуемая минимальная версия fp, по умолчанию 0;
version_revision - требуемая ревизия, напрмер 115, по умолчанию 0;
swf - имя swf файла;
width
height
bgcolor
application - имя swf объекта внутри html.

Если вы используете свой собственный шаблон, то можете определить дополнительные параметры.

Дополнения

Для создания собственного шаблона можно использовать swfobject

Постоянная ссылка 2008-07-08 01:23:58, от agahov Email , 153 слов, Рубрики: Flex, maven , Оставить комментарий »

Сборка простого flex приложения с помощью Flex Mojos

Начальные условия

установленная java jdk 5 или выше.
переменная окружения JAVA_HOME
установленный maven.

Стандартная для maven структура проекта

project-name/pom.xml………………. конфигурационный файл сборки проекта.
project-name/src
project-name/src/main/
project-name/src/main/flex…………. код flex приложения
project-name/src/test
project-name/src/test/flex…………. тесты flex приложения
project-name/src/main/flex/Main.mxml

Структура pom.xml

pom собирающий flex приложение:

XML:

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0" >
 
 
    <parent>
         <groupId>info.rvin.mojo</groupId>
         <artifactId>flex-super-pom</artifactId>
         <version>1.0</version>
    </parent>
 
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.mydomain.mypackage</groupId>
    <artifactId>myArtifactId</artifactId>
    <packaging>swf</packaging>
    <name>myArtifactName</name>
    <version>1.0</version>
 
    
    <repositories>
                <repository>
                        <id>flex-mojos-repository</id>
                        <url>http://svn.sonatype.org/flexmojos/repository/</url>
                        <releases>
                                <enabled>true</enabled>
                        </releases>
                </repository>
     </repositories>
 
    <pluginRepositories>
        <pluginRepository>
          <id>flex-mojos-repository</id>
          <url>http://svn.sonatype.org/flexmojos/repository/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </pluginRepository>
      </pluginRepositories>
 
</project>

Запуск сборки проекта с помощью maven

Для сборки приложения необходимо набрать в командной строке,
project-name> mvn install

Рассмортим pom.xml по частям

XML:

<parent>
    <groupId>info.rvin.mojo</groupId>
    <artifactId>flex-super-pom</artifactId>
    <version>1.0</version>
</parent>

тег parent определяет родительский pom, для текущего pom.
В maven, текущий проект наследует свойства родительского.
В качестве родительского pom, для flex проекта здесь выступает flex-super-pom, который является частью flex-mojos. В нём определены многие полезные параметры, которые можно использовать по умолчанию. В своём проекте вы можете использовать собственный parent, взяв из flex-super-pom только необходимое.

Следующие теги определяют ваш артефакт в репозитории maven. В дальнейшем вы сможете использовать данный артифакт в других проектах.

XML:

<groupId>com.mydomain.mypackage</groupId>
    <artifactId>myArtifactId</artifactId>
    <packaging>swf</packaging>
    <name>myArtifactName</name>
    <version>1.0</version>

Стоит отметить

XML:

<packaging>swf</packaging>

- определяет тип артифакта, для библиотеки это swc.

XML:

<repositories>
                <repository>
                        <id>flex-mojos-repository</id>
                        <url>http://svn.sonatype.org/flexmojos/repository/</url>
                        <releases>
                                <enabled>true</enabled>
                        </releases>
                </repository>
     </repositories>

тег repositories определяет перечень репозиториев, в которых можно осуществлять поиск артифактов.

XML:

<pluginRepositories>
        <pluginRepository>
          <id>flex-mojos-repository</id>
          <url>http://svn.sonatype.org/flexmojos/repository/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </pluginRepository>
      </pluginRepositories>

тег pluginRepositories определяет перечень репозиториев, в которых можно осуществлять поиск maven плагинов.

Полезные дополнения

Удаление артефактов осуществляется командой project-name>mvn clean
Генерация asdoc, осуществляется командой project-name>mvn asdoc:asdoc
Команды можно комбинировать, например project-name>mvn clean install

Что ещё может Flex mojos?

Компелить SWF, SWC, ASWF, ASWC.
Запускать тесты.
Поддерживать RSL.
Оптимизировать, шифровать swf.
Создавать html wrapper,
В итоге собирать сложные проекты, включающие библиотеки, стили, локализацию, flex модули.

Плюсы использования maven для flex сборки

По моему опыту плюсом является стандартизация структуры проекта. Для того что бы понять что откуда берёться, достаточно посмотреть pom.xml.

Постоянная ссылка 2008-07-04 10:59:45, от agahov Email , 1728 слов, Рубрики: Flex, maven , 4 комментариев »

Flex Mojos - A Maven Flex Plugin

Недавно вышел новый Flex Mojos - A Maven Flex Plugin. Если вы собираетесь внедрять maven, рекомендую к нему присмотреться.

Сборка приложения использующего BlazeDS, Spring, Hibernate. очень хорошо описана в наборе статей (Flex, Spring and BlazeDS: the full stack! part 1, part2 , part3, part4)

Постоянная ссылка 2008-07-03 10:18:53, от agahov Email , 21 слов, Рубрики: Flex, AS3, maven , 2 комментариев »

Flex + Maven часть1

Для сборки flex c помощью maven необходимо произвести следующие действия:
- установить MAVEN
- установить flex sdk
- создать файл проекта pom.xml
- настроить среду
- создать структуру проекта и Main.mxml
- запустить maven

Создание файла проекта pom.xml
плагин для сборки swf/swc http://www.israfil.net
пример pom.xml для flex

XML:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
    <name>test-flex-swf</name>
    <groupid>test</groupid>
    <artifactid>test-flex-swf</artifactid>
    <version>1.0</version>
    <modelversion>4.0.0</modelversion>
    <description>test build flex with maven.
    see: </description>">http://riapriority.com/blogs/agahov.php</description>
 
    <packaging>swf</packaging>
 
  <properties>
                <flex .home>C:/FLEX_HOME/sdk/2.0.1</flex>
      </properties>
    <build>
        <plugins>
            <plugin>
                <groupid>net.israfil.mojo</groupid>
                <artifactid>maven-flex2-plugin</artifactid>
                <extensions>true</extensions>
                <configuration>
        <flexhome>${flex.home}</flexhome>
                    <mainmxmlfile>Main.mxml</mainmxmlfile>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Настройка среды
- flex.home в pom.xml должна ссылаться на flex sdk, которую вы хоти использовать для сборки

не забудте в файле $flex.home/frameworks/flex-config.xml отредактировать следующую строку:
winFonts.ser - для windows
macFonts.ser - для MAC

XML:

<flex -config>
        <compiler>
                <fonts>
                        <local -fonts-snapshot>---Fonts.ser</local>
                </fonts>
        </compiler>
</flex>

Cтруктура проекта
project-name/pom.xml
project-name/src
project-name/src/main/
project-name/src/main/flex
project-name/src/test
project-name/src/main/flex/Main.mxml

Main.mxml может быть таким:

XML:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
  <![CDATA[
    import mx.controls.Alert;
    
    private function start():void
    {
      Alert.show("hi maven!");
    }
  ]]>
</mx:Script>
 
  <mx:Button click="start()"/>
</mx:Application>

Сборка проекта с помощю maven
для сборки проекта зайдите в папку [project-name] и выполните команду: mvn pakage

исходники

Постоянная ссылка 2007-11-27 11:00:10, от agahov Email , 325 слов, Рубрики: Flex, AS3, maven , 4 комментариев »

Клонирование объектов утилитой ObjectUtil.copy

Нам понадобилось клонировать объект. Для этого в as3 можно использовать утилиту ObjectUtil.copy. Метод ObjectUtil.copy(obj) возвращает копию исходного объекта obj. Это замечательно работает для невизуальных объектов.
Пример:

  1. package com.test
  2. {
  3.         public class TestClass
  4.         {
  5.                 public var index : int = 100;
  6.         }
  7. }
  8.  
  9. ...
  10. var testObject:TestClass = new TestClass();
  11. testObject.index = 98;
  12. var cloneTestObject : Object = ObjectUtil.copy(testObject);
  13. trace(“cloneTestObject.index : ” + cloneTestObject); // cloneTestObject.index : 98
  14. ...

Но есть ложка дегтя. Данная функция возвращает анонимный объект. И система не позволяет осуществить его приведение к исходному классу.
Данный код приведет к сбою в программе:

  1. ...
  2. var testObject:TestClass = new TestClass();
  3. testObject = 99;
  4. var cloneTestObject : TestClass = ObjectUtil.copy(testObject) as TestClass;
  5. trace(index: ”+  cloneTestObject.index);
  6. ...

После некоторых исследований и подсказки Константина Ковалёва, находим метод flash.net.registerClassAlias. Который и решает проблему:

  1. ...
  2. var testObject:TestClass = new TestClass();
  3. registerClassAlias(getQualifiedClassName(testObject), TestClass);
  4. var cloneTestObject : TestClass = ObjectUtil.copy(testObject) as TestClass;
  5. ...

Для тех, кто хочет докопаться до сути процесса. В справке по registerClassAlias написано: «LocalConnection, ByteArray, SharedObject, NetConnection and NetStream are all examples of classes that encode objects in AMF.» Так как метод ObjectUtil.copy, использует ByteArray, то наш результирующий объект кодируется в формат AMF. Для восстановления класса объекта, используется функция flash.net.registerClassAlias.

Постоянная ссылка 2007-05-08 11:30:56, от agahov Email , 654 слов, Рубрики: Flex, AS3 , 4 комментариев »

1 2 >>