หน้าเว็บ

วันจันทร์ที่ 30 กันยายน พ.ศ. 2556

custom JSF primefaces lazyLoad with Spring data

บทความที่เกี่ยวข้อง  Lazy load primefaces

        พอดี ผมเองก็ใช้ JSF primeface ร่วมกับ spring data มาได้จะ 2 ปีแล้วครับ  ทุกๆ  โปรเจ็ค  ที่ต้องมีการเรียกใช้งาน lazy load  ร่วมกับ spring data เราต้องมา implement เองในบางส่วน  ซึ่งก็ต้อง implement ทุกๆ class ที่ทำหน้าที่เป็น lazy  หลังๆ เริ่มเบื่อ  เพราะ code มันซ้ำซ้อนในบางที่  ถามว่าเยอะมั้ย  ก็ไม่ได้เยอะมากครับ  แต่ผมอยากเขียนโดยไม่ต้องสนใจส่วนที่มันไม่เกี่ยวข้องกับ core business จริงๆ  คือ อยากให้มันง่าย  และสั้นที่สุดเท่าที่จะทำได้  ก็เลยมานั่งเขียน library ง่ายๆ เอาไว้ใช้เองนิดหน่อย  โดยใช้วิธีการ reflection แล้วก็ทำสิ่งเล็กๆ น้อยๆ ให้เสร็จสับเป็น spring data ทีเดียว  ก่อนที่จะเอาไปใช้งานจริงๆ  ครับ (ตัวอย่างการใช้งานอยู่ล่างสุด)

        จากบทความ  Lazy load primefaces  ถ้าเราเขียนโดยใช้ lazy load ของ primeface แบบธรรมดา  เราก็จะต้องเขียน code ยาวนิดนึงครับ  แต่ถ้าใช้ class ดังต่อไปนี้  ที่ผมเขียนไว้  code คุณจะเหลือแค่ไม่กี่บรรทัด
(เขียนไว้ใช้เองครับ  ซึ่งอาจจะไม่รองรับในทุกกรณี)

Library

LazyLoad.java
package com.blogspot.na5cent.web.lazyload;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.Id;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

/**
 *
 * @author redcrow
 */
public abstract class LazyLoad<T> extends LazyDataModel<T> {

    private static final Logger LOG = LoggerFactory.getLogger(LazyLoad.class);
    private List<T> list;
    private long totalElements;
    //

    @Override
    public T getRowData(String id) {
        if (list != null) {
            for (T instance : list) {
                Object instanceId = getIdOfInstance(instance);
                if (instanceId != null && id.equals(instanceId.toString())) {
                    return instance;
                }
            }
        }

        return null;
    }

    private Object getIdOfInstance(Object instance) {
        Object instanceId = null;
        try {
            Class instanceClass = instance.getClass();
            Field[] fields = instanceClass.getDeclaredFields();
            Field idField = null;
            for (Field field : fields) {
                if (field.isAnnotationPresent(Id.class)) {
                    idField = field;
                    break;
                }
            }

            if(idField != null){
                String idName = idField.getName();
                idName = idName.substring(0, 1).toUpperCase() + idName.substring(1);
                Method method = instanceClass.getDeclaredMethod("get" + idName);
                instanceId = method.invoke(instance);
            }
        } catch (Exception ex) {
            LOG.warn(null, ex);
        }

        return instanceId;
    }

    @Override
    public Object getRowKey(T instance) {
        return getIdOfInstance(instance);
    }

    @Override
    public void setRowIndex(final int rowIndex) {
        if (rowIndex == -1 || getPageSize() == 0) {
            super.setRowIndex(-1);
        } else {
            super.setRowIndex(rowIndex % getPageSize());
        }
    }

    /**
     *  callback method
     */
    public abstract Page<T> load(Pageable page);

    @Override
    public List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        Sort.Direction direction;
        if (sortOrder == SortOrder.ASCENDING) {
            direction = Sort.Direction.ASC;
        } else {
            direction = Sort.Direction.DESC;
        }

        Page<T> page = load(new PageRequest(first / pageSize, pageSize, direction, sortField));
        if (page != null) {
            list = page.getContent();
            totalElements = page.getTotalElements();
            this.setRowCount((int) totalElements);
        } else {
            list = new ArrayList<>();
            totalElements = 0L;
            setRowCount(0);
        }

        return list;
    }

    public List<T> getContents() {
        return list;
    }

    public long getTotalElements() {
        return totalElements;
    }
}

ตัวอย่างการใช้งาน เมื่อเรียกใช้ library (LazyLoad.java)


วันพุธที่ 25 กันยายน พ.ศ. 2556

spring session scope in JSF managedbean

บทความที่เกี่ยวข้องกัน  JSF ManagedBean can @Autowire Spring resources : java, JSF

พอดี  มีเหตุการณ์บางอย่างครับ  ที่ทำให้ไม่สามารถใช้ @SessionScoped ของ JSF ได้  ก็เลยต้องมาใช้ session scope ของ spring แทน

จาก  code ผมได้ทำการทดสอบ  ว่า session scope นี้ใช้งานที่จริงๆ หรือไม่   โดย

1. ทำการสร้าง method postConstruct(@PostConstruct) ขึ้นมา   เพื่อ check ว่า bean นี้จะต้องถูกสร้างเพียงครั้งเดียว ต่อ 1 http session เท่านั้น  คือมันจะเรียก method postConstruct เพียงแค่ครั้งเดียว (หลังจากที่เรียก contructor) จนกว่า session นั้นจะ expire ไป

2. ทำการ set ค่าลงใน http session (session.setAttribute("blogName", "na5cent")) เพื่อ check ว่าสามารถดึงค่านั้นออกมาใช้งานได้หรือไม่

ซึ่งเป็นไปตามที่ทำการทดสอบทั้ง 2 อย่าง  คือสามารถใช้ @Scope(value="session") ของ spring แทน @SessionScoped  ของ JSF ได้ครับ

HomePageController.java
package com.blogspot.na5cent.web.controller;

import java.io.Serializable;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct;
//import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 *
 * @author recrow
 */
@Component
@Scope(value = "session")
//@SessionScoped
public class HomePageController implements Serializable{
    
    private static final Logger LOG = LoggerFactory.getLogger(HomePageController.class);
    private AtomicInteger counter = new AtomicInteger(0);
    
    @PostConstruct
    public void postConstruct(){
        LOG.debug("counter => {}", counter.incrementAndGet());
    }
    
    public String getWelcomeMessage(){
        HttpSession session = (HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        session.setAttribute("blogName", "na5cent");
        return (String) session.getAttribute("blogName");
    }
}

index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        
    </h:head>
    <h:body>
       Managedbean message : #{homePageController.welcomeMessage}<br/>
       EL message :  #{session.getAttribute('blogName')}
    </h:body>
</html>


วันจันทร์ที่ 16 กันยายน พ.ศ. 2556

java 7 show disk space


maven dependencies (pom.xml)
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
            <type>jar</type>
        </dependency>
    </dependencies>

    ....
    ....
    ....
DiskSpace.java
package com.blogspot.na5cent.diskspace;

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.FileSystemException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.commons.io.FileUtils;

/**
 * @author redcrow
 */
public class DiskSpace {

    public static void main(String[] args) throws IOException {
        for (Path root : FileSystems.getDefault().getRootDirectories()) {
            System.out.println(root);

            try {
                FileStore store = Files.getFileStore(root);
                long totalSpace = store.getTotalSpace();
                long freeSpace = store.getUsableSpace();
                long usedSpace = totalSpace - freeSpace;
                
                System.out.println("free space = " + diskSize(freeSpace));
                System.out.println("used space = " + diskSize(usedSpace));
                System.out.println("total space = " + diskSize(totalSpace));
            } catch (FileSystemException ex) {
                System.out.println("FileSystemException " + ex.getMessage());
            }
            
            System.out.println("===================================================");
        }
    }
    
    private static String diskSize(long size){
        return FileUtils.byteCountToDisplaySize(size);
    }
}

วันเสาร์ที่ 14 กันยายน พ.ศ. 2556

error handler requirejs

require.config({
    catchError: true
});

requirejs.onError = function(error) {
    console.log('module error');
    console.log(error);
};


require(['doseNotExistScript'], function(){

});

Agents.js (modify code jquery browser)

Agents.js
var Agents = (function(window) {
    var userAgent = window.navigator.userAgent.toLowerCase();

    var match = /(chrome)[ \/]([\w.]+)/.exec(userAgent) ||
            /(webkit)[ \/]([\w.]+)/.exec(userAgent) ||
            /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(userAgent) ||
            /(msie) ([\w.]+)/.exec(userAgent) ||
            userAgent.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(userAgent) || [];

    var platformMatch = /(ipad)/.exec(userAgent) ||
            /(iphone)/.exec(userAgent) ||
            /(android)/.exec(userAgent) || [];

    var name = match[1] || '';
    var version = match[2] || '';
    var platform = platformMatch[0] || '';
    var engine = '';

    if (name === 'chrome') {
        engine = 'webkit';
    } else if (name === 'webkit') {
        name = 'safari';
        engine = 'webkit';
    } else if (name === 'mozilla') {
        name = 'firefox';
        engine = 'mozilla';
    } else if (name === 'msie') {
        engine = 'trident';
    }

    var isChrome = (name === 'chrome');
    var isFirefox = (name === 'firefox');
    var isMSIE = (name === 'msie');
    var isSafari = (name === 'safari');
    var isWebkit = (engine === 'webkit');
    var isTrident = (engine === 'trident');
    var isMozilla = (engine === 'mozilla');

    return{
        getName: function() {
            return name;
        },
        getVersion: function() {
            return version;
        },
        getPlatform: function() {
            return platform;
        },
        getEngine: function() {
            return engine;
        },
        isChrome: function() {
            return isChrome;
        },
        isFirefox: function() {
            return isFirefox;
        },
        isMSIE: function() {
            return isMSIE;
        },
        isSafari: function() {
            return isSafari;
        },
        isWebkit: function() {
            return isWebkit;
        },
        isTrident: function() {
            return isTrident;
        },
        isMozilla: function() {
            return isMozilla;
        }
    };
})(window);

/**
* example to use
*
* Agents.getName();
* Agents.getVersion();
* Agents.getPlatform();
* Agents.getEngine();
*
* Agents.isChrome();
* Agents.isFirefox();
* Agents.isMSIE();
* Agents.isSafari();
*
* Agents.isWebkit();
* Agents.isTrident();
* Agents.isMozilla();
*/
thank you :  http://api.jquery.com/jQuery.browser/