Wednesday, November 04, 2009

Compress all output and speed up download big js files

We can speed up downloads or web page access time with Apache mod_deflate module. The mod_deflate module provides the DEFLATE output filter that allows output from our server to be compressed before being sent to the client over the network.

This decreases the amount of time and data transmitted over the network, resulting in faster web experience or downloads for visitors.

Today we add the following config in our Apache server,

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript

And our js file size are huge reduced. The big one reduce as follow:

ext-all.js - from 609 k to 167 k
home_mini.js - from 523 k to 101 k

It makes our site load really quick and it is really help. You can try it at our site: www.feyasoft.com

Notice

Enabling filters with AddOutputFilterByType may fail partially or completely in some cases. For example, no filters are applied if the MIME-type could not be determined and falls back to the DefaultType setting, even if the DefaultType is the same.

However, if you want to make sure, that the filters will be applied, assign the content type to a resource explicitly, for example with AddType or ForceType. Setting the content type within a (non-nph) CGI script is also safe.

Ok, here are the details steps to create it:

# cd /usr/local/apache/config/
# vi httpd.conf
Add the following line:

LoadModule deflate_module modules/mod_deflate.so
< Location / >
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript
< /Location >
And now your need restart apache. If you did not have mod_deflate.so in your apache. Ok, now you need config and build one from apache source code. Here is a good link for your:

http://streetsmartingit.blogspot.com/2007/11/how-to-compileinstall-moddeflate-into.html

Thursday, October 29, 2009

Online PowerPoint 1.0.0 Beta is released

After a while, online PowerPoint 1.0.0 Beta is released. And you can insert Text and Image in this version. And you can Drag and Drop the item. Finally you can review it.

See detail demo @ www.feyasoft.com and login as: demo/demo

Tuesday, August 04, 2009

New version of Online Calendar release

We just push another version of our calendar online. Have a look if you shows interesting. It includes the following features:

1: Day/Week/Month view
2: DnD, Resize
3: Support Multiple Calendar

We will continue add more features in the near future.

To see/use it, you can login: http://www.feyasoft.com and sign in as Guest or using: demo/demo

Worked in FF, Chrome, IE.

Month View:Week view:Day view:

Saturday, May 09, 2009

Extjs Code Style

Ext JS as a cross-browser JavaScript library, it is a really flexible language. Two peoples have different code style will generate totally different code. So it is really important for us to follow some standard - especial for the piece of code share between groups memeber. Here list some coding standard shared in our group:



1: File Structure and name

Because UI level can be easily divided as center/south/east/west/noth panel. For each page - especial complex UI, we will always create a folder for each panel, such as: Center, South etc. And we always put the share files into the common folder.

In a words, the file and folder should be easy to connect to the UI level - this will save lots of time for future maintainance.

And namespace will be always used for each folder: Ext.ns('feyaSoft.calendar.dayView')

2: Define the Class

The target of extjs is to achieve complex UI. Obviously this includes part of logic to achieve UI behavior. To make code readable and reusable, we'd better separate the logic code and UI code. For example:


Ext.ns("feyaSoft.main");

feyaSoft.main.MainPanel = function(){
....
// down tab panel
this.downTabPanel = new Ext.TabPanel({
region: 'south',
tabPosition: 'bottom',
activeTab: 0,
deferredRender: false,
layoutOnTabChange:true,
height: 190,
split:true,
resizeTabs:true,
tabWidth:200,
minTabWidth: 120,
plugins: new Ext.ux.TabCloseMenu(),

items:[{
title: 'Our Customer\'s Project',
iconCls: 'application',
closable: false,
autoScroll:true,
layout:'fit',
border: false,
cls:'feyasoft-images-view',
items: [this.customerView]
}]
});

....
feyaSoft.main.MainPanel.superclass.constructor.call(this, {
id: 'main_panel_page',
region: 'center',
layout: 'border',
border: false,
items: [this.upTabPanel, this.downTabPanel]
});
};

Ext.extend(feyaSoft.main.MainPanel, Ext.Panel, {

// click customer image link
onCustomerClickFn : function(dv, index, node, e){
var rd = dv.store.getAt(index);
var data = rd.data;
var name = data['name'];

.....
},

....
});

In this way, we can reuse this logic code as we like. And make code really easy to readable.

3: Try to avoid use "id" in the panel/Grid/field etc.

Because id is binded with dom field, there will be only one place work correct when we reuse the same piece of code with id in another place.

In general, the purpose of id is to make get the reference of item in different place , like: Ext.getCmp('myId'). We can achieve this through pass reference or try use: this.ownerCt.reload() to get other item reference.

Some suggestion:

1: Try to reuse the code - if 2 place have similar code, make it comment and reuse
2: Any function and method should not more than 100 line. Try to have sub function/method if it is too big.
3: Try to use this: if (true == flag) instead of: if (flag == true)

Tuesday, April 28, 2009

Upgrade to Grails 1.1

It is a pain process to update to Grails 1.1 (Your know I do not want to read long release notes)

1: Acegi Security failed - need re-run plugin again. (Plugins are now stored in your USER_HOME directory. You will need to re-install your plugins or run: grails -Dgrails.project.plugins.dir =./plugins run-app)

1.1: Install the Acegi plugin
> grails install-plugin acegi

1.2: CREATE THE USER, ROLE, AND REQUESTMAP DOMAIN CLASSES
> grails create-auth-domains User Role Requestmap

1.3: OPTIONAL - CREATE CONTROLLERS AND GSPS FOR USER, ROLE, AND REQUESTMAP DOMAIN CLASSES
> grails generate-manager

1.4: OPTIONAL - CREATE CONTROLLERS AND GSPS FOR CAPTCHA, REGISTER, AND AN EMAILER SERVICE.
> grails generate-registration

1.5: CREATE A CONTROLLER THAT WILL BE RESTRICTED BY ROLE
> grails create-controller Secure

2: Log4j config change - need read document careful.

// log4j configuration
log4j = {
appenders {
rollingFile name: 'homeLog',
fileName: '/var/log/home/full.log',
maxFileSize: 26214400,
maxBackupIndex: 10,
layout: pattern(conversionPattern: '%d{yyyy-MM-dd HH:mm:ss,SSS} %p %c{2} %m%n')
}
root {
error()
additivity = true
}
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages' // GSP

debug fileLog:'grails.app'
warn 'org.mortbay.log'
}

3: Return Date format

I do have date format issue after I upgrade to Grails 1.1. Ok, this is also new feature. Now grails is locale aware and will change the dateformat according to the user's locale. So you need add this to the config.goovy if you have any issue:

grails.converters.json.date = 'javascript' // default or javascipt

Or do something like this:

import grails.converters.JSON;

class BootStrap {

def init = { servletContext ->
JSON.registerObjectMarshaller(Date) {
return it?.format("dd-MM-yyyy")
}
}
def destroy = {
}
}


4: Acegi issue - I run into the issue related Acegi for reDirect (sometimes)

2009-04-29 10:06:27,875 [6216949@qtp0-1] ERROR errors.GrailsExceptionResolver - java.lang.NullPointerException
org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.NullPointerException
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:92)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1061)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:910)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892)
at groovy.lang.Closure.call(Closure.java:279)
at groovy.lang.Closure.call(Closure.java:274)
at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleAction(SimpleGrailsControllerHelper.java:363)
at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.executeAction(SimpleGrailsControllerHelper.java:243)
at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleURI(SimpleGrailsControllerHelper.java:203)
at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleURI(SimpleGrailsControllerHelper.java:138)
at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController.handleRequest(SimpleGrailsController.java:88)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet.doDispatch(GrailsDispatcherServlet.java:264)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)


To make sure it is this problem, temporary you can disable Acegi - set "active = false" in SecurityConfig.groovy.

It looks like it's a filter - Grails implements these using one HandlerInterceptor (CompositeInterceptor) that iterates your configured filters:

at org.codehaus.groovy.grails.plugins.web.filters.CompositeInterceptor$-postHandle-closure1.doCall(CompositeInterceptor.groovy:48)

Thursday, April 23, 2009

Extjs based online Spreadsheet/Excel

After a while, extjs based online Spreadsheet/excel is released. You can view the demo @

www.feyasoft.com -> My Document -> Right Click Mouse(New Spreadsheet)

Currently it has the following features available:

1: Increase columns by auto scroll down the mouse
2: Cut/Copy/Paste
3: Undo/Redo
4: Add/edit/delete comments
5: Save As

There are several features on the list for process:

1: Calculate (Summary, Average, Min, Max etc)
2: Export as Excel/CSV

Thursday, March 19, 2009

Build J2EE application with Extjs + Grails

Running open source calendar app: www.cubedrive.com/myCalendar

For J2EE based web application, it is pretty popular to use light weight J2EE loose coupling concepts in business logic tier, and use Structs/Spring MVC/JSF as web framework in presentation tie. However, more and more customers require simple, quick, easy and affordable solution for their business - for example, how to quick build web-based J2EE application similar with Microsoft Outlook. We, J2EE application architecture/developer, need quick move forward to build Ajax-based rich interface J2EE application. Extjs + Grails are the right frameworks for build web application at the right time (2009 is the cut cost year everywhere).

Ext JS, a cross-browser JavaScript library for building Rich Internet Applications, owns an extensive library of super-high-quality widgets, an intuitive, extensible component model, and an easy-to-use API to create a full, rock-solid platform for JavaScript-based web apps.

Grails is an open source web application framework which leverages the Groovy programming language (which is in turn based on the Java platform). It is intended to be a high-productivity framework by following the "coding by convention" paradigm, providing a stand-alone development environment and hiding much of the configuration detail from the developer.

High Level Architecture Diagram

Figure 1 shows the basic high level architecture for Extjs/Grails-based RIA J2EE application. [1]

Choice widely adopted 3rd-party software

Open source solutions become widely adopted only if they're reliable and deliver value. Using those valuable open sources will buy us more time and better performance for the project. This is the reason we choice the following the 3rd-party software in this application. See table 1 for detail information [2]

3rd-party Software
Reason to choose
Extjs (www.extjs.com)Extjs Ajax framework acts as a glue between browser and server, it enables us to create a rich and intuitive user interfaces for our application. Extjs provides Layout, Grid, Form, Tree, Menu etc which are widely used in our UI level. Furthermore, extjs provides great document/API.
Grails (www.grails.org)Open source web application framework help us to quick build server side logic, which based on spring framework.
Tomcat (tomcat.apache.org)Free application server.
Apache (www.apache.org)Load balance
MySql (www.mysql.org)Free database server.


Rich UI interface - extjs

By using extjs javascript framework, we can easy achieve nearly all of online ajax-based UI stuff. Compare with DOJO (orthodoxy and stability), extjs has more UI widgets, pretty detail API document which will save lots of developer time. Except that you are fine for extjs commercial license.

Extjs provides following widgets:

  • Grid
  • Layout
  • Window
  • Tree
  • Form
  • Menu
  • and lots of active memeber with really useful plugin

Data Exchange

In tradition way, data exchange from backend to frontend are as following

  • Object in database is transfered to DAO POJO object
  • DAO POJO object transfer data to MVC form object
  • Form object display results in page

In Ajax-based application, data exchange can be something like this:

  • Object in database is transfered to DAO POJO object
  • Render POJO object as JSON data to the UI level.

Grails provides great API to make data exchange between extjs and controller seamless.


Grails Acegi plugin for Authentication and Autherization

Grails based acegi security plugin allows developer to use the powerful of spring-based security, but it also gives us the power to make config changes without having to deal with the complexity of using Spring Security directly.

  • Spring Security filters and Spring beans are registered in web.xml and the application context for you; customization is done in SecurityConfig.groovy
  • Domain classes, Controllers, and CRUD GSPs for User and Role management and persistence
  • Ajax-based login and Logout Controllers






Tuesday, January 20, 2009

Integrate Acegi(0.5.1) with Grails

Recently we try to integrate Acegi(0.5.1) into the grails. We follow the document:

http://docs.codehaus.org/display/GRAILS/AcegiSecurity+Plugin+-+Basic+Tutorial

However, this document is not updated with the latest Acegi. You need pay attention to several issue when you create role, requestmap. Otherwise, it will not work for your.

When you create a role, the role name should include "ROLE" (case sensitive): i.e: ROLE_admin. And this is the quick steps to plugin acegi into your grails project:

1.1: Install the Acegi plugin

> grails install-plugin acegi

1.2: CREATE THE USER, ROLE, AND REQUESTMAP DOMAIN CLASSES

> grails create-auth-domains User Role Requestmap

1.3: OPTIONAL - CREATE CONTROLLERS AND GSPS FOR USER, ROLE, AND REQUESTMAP DOMAIN CLASSES

> grails generate-manager

1.4: OPTIONAL - CREATE CONTROLLERS AND GSPS FOR CAPTCHA, REGISTER, AND AN EMAILER SERVICE.

> grails generate-registration

1.5: CREATE A CONTROLLER THAT WILL BE RESTRICTED BY ROLE

> grails create-controller Secure

2.1: Create role

http://localhost:8080/demo/role
attention - And role name should be start with "ROLE" - i.e: ROLE_ADMIN, ROLE_USER

2.2: Create user

http://localhost:8080/demo/user

2.3: create url request map

http://localhost:8080/demo/requestmap
please add the following url:

/user/** /role/** /adminpage/** /requestmap/**
ROLE_ADMIN

2.4: login to admin page

http://localhost:8080/demo/adminpage

Friday, January 16, 2009

Grails JasperReport plugin

Recently we start to play with Jasper plugin for Grails (version 1.0.4), and we did not have lucky to make it work - we use comment line "grails install-plugin jasper" (version 0.9). We always end with this kind of error - my poor hair:
at net.sf.jasperreports.engine.JRPropertiesMap.readObject(JRPropertiesMap.java:185)
After look around for a while, it seems the grails plugin jasper report library version is too old, and it somehow does not work under this version of Grails.

After update to the latest version of jasperReport and iText

iText-2.1.4.jar
jasperreports-3.1.3.jar


and put it into plugins/japser-0.9/lib, now I can generate the PDF file.

And if you are using the latest iReport, you also need pay attention to the xml format of .jrxml. Please follow the example .jrxml to generated your .jasper file.