Monday, December 30, 2013

lesscss workflow for bootstrap under eclipse

Bootstrap source is authorized with lesscss. It can be customized and compiled with lesscss. One reason to do this is using semantic css class.  For example, suppose I have a customer domain object, I'd like to use "customer" css class for form/table. My customer class will be super simple
form.customer
{
  .form-horizontal;
}

Problem with lessc approach

Before I can use this semantic class, I need a customized bootstrap css.   Typical approach is to invoke lessc from command line. For eclipse, there is a plugin to edit and compile lesscss file: http://www.normalesup.org/~simonet/soft/ow/eclipse-less.en.html. There are several problems with this plugin. First, it is not easy to get this work under Window. This plugin will eventually invoke lessc coming with lesscss. lessc is a script interpreted by node.exe. It is script for unix system. lessc is invoked for window like this "node c:\Window\system32\node_modules\less\bin\lessc". Finally, even you can get this work under window, the compilation process is a manual process. It is not integrated into eclipse and maven process flow.

lesscss maven plugin

I did some search and found this wonderful maven plugin :https://github.com/marceloverdijk/lesscss-maven-plugin. First, it does not have external dependency. This plugin uses lesscss4j, a java implementation of lesscss compiler. This is very important in a continuous integration(CI) system since we want to minimize requirement for CI. Moreover, it can be integrate into the maven process management flow by specifying a execution goal.  By default, it is executed in compilation phase. So the final css file is automatically generated by eclipse when less file is changed.  In an environment without eclipse such as CI system,  the css will be generated at compilation stage together with your java code compilation.

Bootstrap customization workflow under eclipse.

  1. Have a separated directory for less file under src/main. In my case, I have src/main/less for less files. Do not leave less files under src/main/webapp. Files under src/main/webapp will be copied to final war. We don't want to distribute less files. 
  2. copy bootstrap less sources file. I copy them to src/main/less/bootstrap/*.less files.
  3. add your-project-specific less file. I have all my project-specific less files under /src/main/less/fragments/*.less. 
  4. Add top less files. This file will import less file from bootstrap and fragment folder.  My example files.
    //-------src/main/less/top.less
    @import "bootstrap/variables.less";
    @import "bootstrap/mixins.less";

    // Reset
    @import "bootstrap/normalize.less";
    @import "bootstrap/print.less";

    // Core CSS
    @import "bootstrap/scaffolding.less";
    @import "bootstrap/type.less";
    @import "bootstrap/code.less";
    @import "bootstrap/grid.less";
    @import "bootstrap/tables.less";
    @import "bootstrap/forms.less";
    @import "bootstrap/buttons.less";


    //project specific
    @import "fragment/props.less";


  5. configure the plugin to compile the top file at compilation stage.
    <plugin>
                    <groupId>org.lesscss</groupId>
                    <artifactId>lesscss-maven-plugin</artifactId>
                    <version>1.3.3</version>
                    <configuration>
                        <sourceDirectory>${project.basedir}/src/main/less</sourceDirectory>
                        <outputDirectory>${project.basedir}/src/main/webapp/css1</outputDirectory>
                        <compress>true</compress>
                    <includes>
                         <include>top.less</include>

                      <include>bootstrap/theme.css</include>
                     </includes>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

Top.css and bootstrap/theme.css are generated automatically any time when the top.less is modified inside of eclipse. You can also trigger the compilation from command line like this: mvn lesscss:compile.


Wednesday, December 11, 2013

Faces Flow is not necessary in JSF

Spring has the nice feature of WebFlow. JSF 2.2 comes with Faces Flow. But I think Faces Flow is not needed in JSF.
First, Let us try to understand why WebFlow is necessary in Spring MVC. Spring MVC is a generic MVC. Itself does not provides any rendering technology. Instead it provides a set of nice hook to make it easy to use other rendering technology such as validation,  data binding, request dispatcher, web flow. But JSF is complete MVC framework with all the features from Spring MVC. For example, JSF takes advantage of EL for bidirectional data-binding. It has clearly defined validation and conversion plugin.  I will compare the WebFlow feature from Spring with similar feature in JSF.

FlowScope

JSF needs to run in CDI context. CDI defines ConversationScope. This is a long-lived versatile scope and be used for anything.  It can be definitely used for scope in flow.

View

A view in JSF can simply be a facelet page. The page will has all the data-binding, validation, rendering from JSF.

Action

In Spring WebFlow, you can execute action, basically method call, in various stages such as beginning or end of the flow, beginning or end of a view, or before rendering a view.
These actions can be implemented in JSF in various ways. First, JSF has PhaseListener, SystemEventListener, etc. You can hook up your event listened to JSF lifecycle, view or a particular component. The possibility is infinite. ActionListener  and Action can also be attached to UICommand. Any business logic can be performed here. We can also perform initialization and cleanup logic for flow using CDI PostConstruct and PreDestroy with ConversationScope bean.

View Branching

Suppose you are going to do transition from one view. The next view is selected based on some outcome result. This just corresponds to JSF navigation case. You can use face-config.xml or embed the logic in your action method.

I can not see any WebFlow features can not be implemented with JSF 2.1.

Note: by the way, Flow from JSF 2.2 is buggy at current stage. Simple static flow management is ok, but a complex method call will give you headache. I suggest you use Conversation instead of Flow to manage a flow.

Wednesday, December 4, 2013

DBMS for a data analysis project.

RDBMS VS NoSQL
Recently, I embarked on a small data analysis project. The project itself does not store any critical data. It retrieves from various sources, guides user through an analysis flow and finally generates a report. The generated report will be stored for future reference. Moreover, there is no scalability and transaction requirement. In conceivable future, it will be used by a dozen of persons. So what is a good technology stack for this?
The standard technology stack for this would be like this
  1. Mysql for database
  2. JPA(hibernate) for persistence
  3. DAO to encapsulate JPA.
  4. JSF/JSP for server-side web technology
  5. Bootstrap/jQuery/Angular JS for client technology 
 SOA and Angular JS are advocated along the way.

Why should RDBMS be used? We need to understand why RDBMS should be used in  the first place. 1)RDBMS is really good for Ad-hoc query through the whole database once indexes is built. But if you rarely do Ad-hoc query, why use it? For example, in one application managing research project, user only accesses his own project. The application does not allow user search/query all projects through various project's properties. In this case, we could organize data by project. We never do a query through project table. 2) RDBMS is good at structured data. If your data are not well defined or change constantly, you will end up modifying the table structure constantly or store most of data structure as blob.  Apparently, this is not a situation RDBMS can handle gracefully. 3) RDBMS excel at managing real-time transaction.

Apparently, NoSql is appropriate for the small data-analysis project mentioned above. First, we do not store any critical data.  The final result (report) is never really intensive queried. Second, we need to capture any information gathered during the analysis process so end user can retrospect how the analysis is performed. Apparently. 'any information' does not have a well defined structure.  The 'any information' can change at any time as the analysis flow is improved or changed. Most likely, the 'any information' will be serialized and stored in database as blob or clob. Third, we do not have transaction requirement.

Another consideration is angular JS. Where does the data come from if the angular JS is used?  Conceivably, WS in server can be designed to channel data in JSON to browser.  I did some research on NoSql database. I found the database CouchDB. CouchDB serves data directly through HTTP API. The data will be in JSON format and it stores data in JSON format, too.  If CouchDB is adopted for this project, I can imagine that even a J2EE server is not needed any more.  We only need HTML+angular js. All dynamic aspects are performed at client side.  What a nice and ligh-weight solution!