Wednesday, April 28, 2010

Flex 3 and Flex 4 - Tips

  • When manually dispatching an event, using uiComponent.dispatchEvent(your-event), you need to add listener to the same component uiComponent. So, uiComponent.addEventListener(type,handler) will work, but uiAnyOtherComponent.addEventListener(type,handler) will not work.
  • The state changes-related transition effects have to correspond to the type of changes between the corresponding states.
    Example: I had a vertical group with two components. In State 1, both components show. In State2, Comp1 is not included. I set a Resize transition for Comp1 and a Move transition for Comp2. The effect was surprising: when state changed, Comp1 disappeared and appeared at the bottom of the screen. There it was re-sized. The right fix was to change Comp1: instead of includeIn=State1, I did height.State2=0. That did the trick.
  • Constraint-based layout is supported only in a container with BasicLayout. If you want to use it inside a VGroup, for example, you can put it inside a Group for which you don't specify any layout (BasicLayout is the default).

    Thursday, April 22, 2010

    Installing Samsung Printer ML-2510 on a Network Server under Win7

    • Go to: Control Panel > Hardware and Sound > Devices and Printers.
    • Click "Add a Printer" and in a new window: Click "Add a local printer".
    • Select "Create a new port" via radio buttons. Select "Standard TCP/IP Port" via dropdown. Click "Next".
    • Enter "192.168.0.2"  or whatever is your print server IP address via textbox "Hostname or IP Address". Modify "192.168.0.102" via textbox "Port Name" if desired. Unselect "Query the printer [...]" via checkbox.
    • Select custom settings and set:
      • Protocol LPR and Queue Name L1 and enable LPR Byte Counting.
    • Reach page "Install the print driver".
    • Select "Samsung" via scroll list "Manufacturer". Click "Windows Update" if "Samsung ML-2510 Series" does not appear in scroll list "Printers".
    • [Additional procedures may be needed to continue with printer addition]
    • Reach situation in previous step. Select "Samsung" and "Samsung ML-2510 Series". Click "Next".
    • [Additional procedures may be needed to complete printer addition]

    Monday, April 19, 2010

    Persistence Layer for Flex-and-Java Applications And The Like

    1. Introduction

    When architecting an RIA (aka Web 2.0) application, you have to decide how do you implement the persistence layer. Using the ORM is a standard nowadays, so it's given.  Question as to which ORM to use, got easier with strong acceptance of the Sun's JPA standard by the industry. But, how do you apply ORM in an RIA application is not a question with just a one obvious answer. On one side, the choice of the framework (and the architecture with it). This is presented in section 2. Section 3 presents another aspect of persistence layer: session management, that is how you actually use ORM to persist detached objects (detached, because they are received from outside of the application, namely from the client, for example a Flex client).

    2. ORM in an RIA Application

    Popular options are listed below. Each with advantages and disadvantages.

    2.1. Just-JPA Approach:
    • LCDS, BlazeDS or another Flex remoting framework
    • JPA (in general: ORM) on the server-side, with an object mapper like Dozer
    Pros and Cons:
    • Pro: Simple and a popular choice.
    • Con: Doesn't let you take advantage of ORM's lazy loading and lazy initialization.
      2.2. LCDS with Built-In Hibernate Adapter:

      This solution requires you to purchase a commercial heavy-duty Flex remoting framework Adobe LCDS (LiveCycle Data Services). If you go this way, to integrate it with persistence layer, you create a Hibernate assembler class on the server (Java) and point the LCDS destination to it, as described here.

      Pros and Cons:
      • Pro: (I believe) it takes advantage of lazy loading and initialization.
      • Cons: all of the persistence layer is implemented on the client which can lead to bigger/fatter client.
      • Cons: expense.
      • Cons: proprietary solution.
      2.3. BlazeDS with Gilead:

      Open source solution. Described in detail here.

      Pros and Cons:
      • Pro: open-source; no vendor lock-in.
      • Cons: unknown.
      2.4. GraniteDS:

      Provides a complete open-source solution. Described in a nutshell in comment to this article. More complete information, and a comparison with LCDS-with-Hibernate-assembler option, can be found in this article by the same person (as the comment), William Drai. This article has also more general, highly useful, background on the topic as a whole.

      Pros and Cons:
      • Pro: open-source; no vendor lock-in.
      • Cons: unknown
      3. Persisting Detached Objects

      The three most common applicable persistence design patterns are (as described by Hibernate documentation):
      • session per requestThe most common solution. A single Session and a single database transaction implement the processing of a particular request event. Do never use the session-per-operation anti-pattern.
      • session per conversationOnce persistent objects are considered detached during user think-time and have to be reattached to a new Session after they have been modified.
      • session-per-request-with-detached-objectRecommended. In this case a single Session has a bigger scope than a single database transaction and it might span several database transactions. Each request event is processed in a single database transaction, but flushing of the Session would be delayed until the end of the conversation and the last database transaction, to make the conversation atomic. The Session is held in disconnected state, with no open database connection, during user think-time.
      For another good article on this topic see this.

      3.1 More about Session-Per-Request Pattern

      Let's assume we have an application an RIA with stateless EJB's on the server side. Each request gets a new EntityManager injected. I suggest the following approach to implement session-per-request:
      • if we receive a new object, persist it using
            entityManager.persist(entity)
      • if we receive an object, that is already in the database, use
            entityManager.merge(entity)
      There is one narrow case, when this wouldn't work as expected: when we have a bidirectional association between Invoice and InvoiceDetail and we receive and invoiceDetail with the field invoice set to null. If we apply the method as above, the merge() will reset the invoice in invoiceDetail to null, while the field invoiceDetails in invoice object will continue pointing to invoiceDetail. However, I consider this not a practical case.

      4. Conclusion
      So, a simple starting point that I recommend for your RIA application is to use just JPA with a session-per-request persistence pattern. It can be as simple as:

      JpaDao {
        public void persist(E entity) {
          if (entity.getId() == null) {
            entityManager.persist(entity);
          } else {
            entityManager.merge(entity);
          }
        }
      }
      as suggested by Marcell Manfrin (in a comment).

      4. My Recommended Solution

      • Use JPA with an ORM provider of your own. 
      • Use only JPA annotations and avoid using native provider's annotations. If you have to use a provider's native application, mark it in the code in an easy to discover way.
      • Use session-per-request approach with object mapper like Dozer.
      • Unless domain model is very simple and used only in CRUD-like way, use DTO objects to transfer data between client and server (article).

        • Question: use simple domain objects with public fields?
      • Use service facade layer to:

        • manage session-per-request
        • map domain to/from DTO objects
        • isolate the client from the server
        • provide an lightweight API for the client rather than exposing the client to a complex domain model.

      Flex 4, Spark Architecture Overview: Notes

      Based on a great article by Deepa Subramaniam.

      Intro
      • Every Spark component consists of the skin class (defined declaratively via an MXML file) and a component class (defined via ActionScript).
      • Previous Flex component architecture and component set was MX, aka as Halo.
      • Spark components extend the MX class mx.core.UIComponent, and so Spark containers can hold MX components and vice-versa, and Spark and MX components can live side-by-side. The same component lifecycle methods, properties, and events that existed for the MX components apply to Spark components.
      Skinning

      Three key elements— data, parts, and states—define the skinning contract upon which Spark is founded:
      • Every Spark component class:

        • defines the data the component expects, 
        • defines the constituent parts that make up the component (aka skin parts), and 
        • defines the states the component can enter and exit; responsible for all of the event handling needed to identify when a state change has occurred and ensures the component is put in the right state.
      • The corresponding skin class:

        • how that data is visually displayed, 
        • how the parts are laid out and visualized (it instantiates the parts), and 
        • what the component looks like as it enters and exits different states.
      New Capabilities of Spark Architecture
      • Effects in Spark: faster and more capable; can be invoked directly within Spark skin classes through state-based transitions.
      • New layouts


        • APIs for robust 2D and 3D transformations,
        • the ability to easily implement custom layouts
        • assignable layout

        • FXG and MXML Graphics: graphics library that captures drawing primitives as simple MXML tags. FXG is a declarative XML syntax for defining vector graphics in applications built with Flex and can be created by Adobe Illustrator (or manually) and understood by other Adobe CS tools as well as by FlashPlayer (and probably created and read by Catalyst).
        What Next
        For more information, read references from the base article  by Deepa Subramaniam. For examples and details on skinning read article by Ryan Frishberg. For more information on FXG, read this Adobe well written documentation.

          Thursday, April 1, 2010

          JPA with Hibernate on Glassfish 3

          Intro
          This post is simply a summary of a simple proof of concept. It shows how to:
          • create a stateless EJB3 bean
          • persist an entity using JPA with Hibernate as a JPA provider
          • configure JPA to use a datastore defined on Glassfish (uses pre-installed java/__default datastore, which uses pre-installed Derby/JavaDB) 
          You can download the source code for this sample from here (EJB3_First_Project_with_Test.zip).
           

          Entity
          @Entity
          public class Book implements Serializable {
           @Id
           @GeneratedValue(strategy = GenerationType.AUTO)
           private int id;
           private String title;
           private float price;
           
           public Book() {
              super();
           }
          ...
          }
          
          Here, I have annotated the property, rather than the getter (not shown for brevity), since it feels more intuitive to me. I don't know if there is any advantage/difference of one vs the other other than my personal preference. The "@GeneratedValue(...)" annotation for primary key in JPA entity definition is not optional, as I expected. Using just the "@Id" annotation results in the primary key being not set (set to 0).


          EJB Bean
          The interface:
          @Remote
          public interface BookManager {
           public abstract int addBook(Book book);
           public abstract Book find(int bookId);
          }
          

          And the bean implementation:
          @Stateless(name="BookManager", mappedName = "ejb/BookManagerJNDI")
          @TransactionAttribute(TransactionAttributeType.REQUIRED)
          public class BookManagerImpl implements BookManager {
          
           // Dependency injection of Entity Manager for
           // the given persistence unit
           @PersistenceContext(unitName="pu1") EntityManager em;
           
           public int addBook(Book book) {
          
            // Transitions new instances to managed. On the
            // next flush or commit, the newly persisted
            // instances will be inserted into the datastore.
            em.persist(book);
            
            return book.getId();
           }
           
           @Override
           public Book find(int bookId) {
            return em.find(Book.class, bookId);
           }
          }
          

          The annotation @Stateless with the mappedName make the bean to get registered with JNDI. The
          TransactionAttributeType.REQUIRED tells the container to wrap each method in the class with a transaction.
           
          JPA Setup
          The persistence.xml file (put it into META-INF folder under src folder so it will be deployed onto the server)
          <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
              <persistence-unit name="pu1">
               <!-- Persistence provider -->  
                  <provider>org.hibernate.ejb.HibernatePersistence</provider>
                  <jta-data-source>jdbc/__default</jta-data-source>
          
                  <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
             <property name="hibernate.hbm2ddl.auto" value="create" />
             <property name="hibernate.show_sql" value="true" />
                  </properties>
              </persistence-unit>
          </persistence>
          

          The "hibernate." prefix in persistence.xml file is not optional when adding properties of the JPA provider (Hibernate in this case). They are ignored without it, without a warning.

          Glassfish Setup
          Nothing other than installing the Hibernate component using the Glassfish console.

          Unit Tests
          The unit test:
          try {   
             InitialContext ctx = new InitialContext();
             BookManager bean = (BookManager) ctx.lookup("ejb/BookManagerJNDI");
             Book book = new Book("Chocolate Rain", 25.10f);
             int bookId = bean.addBook(book );
             book = null;
             
             book = bean.find(bookId);
             Assert.assertEquals("Chocolate Rain", book.getTitle());
            } catch (NamingException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
             Assert.fail("Failed. Exception thrown.");
            }
          

          A Few Notes
          • Can JPA be used to create and index? Yes and no. Not in general. But it provides a limited capability. To create a unique constrain on a table, use @UniqueConstraint(columnNames={"EMP_BDAY", "EMP_NAME"})
            • How to specify the character column type length? Use @Column(length=50).
            • What the client can understand about the remote exception, in case the EJB bean fails? The remote exception is wrapped in a EJBException and returned to the client. For example, if the password for the DB is incorrect, the org.hibernate.exception.GenericJDBCException will be returned with a message "Cannot open connection" (when Hibernate is used as JPA provider).
             Conclusion
            A few things to try in the next proof of concept:
            • test the rollback function, if second of two persistence operations failed when both are in the same method of the BookManager class.
            • do a parent/child relationship.