Saturday, December 13, 2014

jQuery rounding number to nearest, flooring or ceiling as expected decimal point


function roundNumber(value, exp) {
    return decimalAdjust('round', value, exp);
}

function floorNumber(value, exp) {
    return decimalAdjust('floor', value, exp);
}

function ceilNumber(value, exp) {
    return decimalAdjust('ceil', value, exp);
}

function decimalAdjust(type, value, exp) {
    // If the exp is undefined or zero...
    if (typeof exp === 'undefined' || +exp === 0) {
        return Math[type](value);
    }
    value = +value;
    exp = +exp;
    // If the value is not a number or the exp is not an integer...
    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
        return NaN;
    }
    // Shift
    value = value.toString().split('e');
    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
    // Shift back
    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}

jQuery Rounding Number To Nearest Interval Such: 0.05, 0.5, 0.1, 5, 10, 100

JSFIDDLE LINK ||| TEXT LINK

Html Content:
<input type='text' name='number' style='width: 150px;' value='10.21'/>
<input type='text' name='round' style='width: 50px;' value='0.25'/>
<input type='text' name='dp' style='width: 50px;' value='2'/>
<input type='button' name='check' value='Check'/>
<div></div>

jQuery Content:


var div = $("div");
log("---------------------------------------------------------");

$("input[type='button']").click(function() {
    var number = parseFloat($("input[name='number']").val());
    var round = parseFloat($("input[name='round']").val());
    var dp = parseFloat($("input[name='dp']").val());
    if (!isNaN(number) && !isNaN(round) && !isNaN(dp)) {
        var nn = roundInterval(number, round, dp, "up");
        
        log("<br/>Rounding: " + numberToString(number, dp, true) + 
            " using: " + round + 
            "/" + "<span class='up-down'>Up</span>" + 
            " as: " + numberToString(nn, dp, true));
        
        var nn = roundInterval(number, round, dp, "down");
        
        log("<br/>Rounding: " + numberToString(number, dp, true) + 
            " using: " + round + 
            "/" + "<span class='up-down'>Down</span>" + 
            " as: " + numberToString(nn, dp, true));
        
        log("---------------------------------------------------------");
    }
});
$("input[type='button']").trigger("click");

function roundInterval(number, interval, round, roundType) {
    if (round > 9) {
        round = 9;
    }
    else if (round < 0) {
        round = 0;
    }
    number = number > 999999999999999 ? 999999999999999 : number;
    var isMinus = false;
    if (number < 0) {
        isMinus = true;
        number = number * -1;
    }
    number = parseFloat(numberToString(number, round));
    interval = parseFloat(numberToString(interval, round));
    var multiplier = roundType == 'up' ? Math.ceil(number / interval) : Math.floor(number / interval);
    
    log("Multiplier: " + multiplier);
    log("As: " + number + "/" + interval + " :: " + (number/interval));
    
    number = multiplier * interval;
    
    number = multiplier * interval;
    if (isMinus) {
        number = number * -1;
    }
    return parseFloat(number.toFixed(round));
}

function numberToString(number, dp, asDp) {
    var format = '#';
    if (asDp === undefined || asDp == null) {
        asDp = false;
    }
    if (dp !== undefined && dp != null && !isNaN(dp)) {
        if (dp > 9) {
            dp = 9;
        }
    }
    else {
        dp = 0;
    }
    if (dp > 0 && asDp) {
        format += ".";
        format += "0000000000".substr(0, dp);
    }
    else if (dp > 0) {
        format += ".";
        format += "##########".substr(0, dp);
    }
    number = number.toString();
    var minus = number.substr(0, 1) == '-' ? '-' : '';
    var ln = "";
    if (number.lastIndexOf("e+") > -1) {
        ln = number.substr(0, number.lastIndexOf("e+"));
        for (var i = ln.length - 2; i < parseInt(number.substr(number.lastIndexOf("e+") + 1)); i++) {
            ln += "0";
        }
        ln = ln.replace(/[^0-9]/g, '');
        number = ln;
    }
    var tail = format.lastIndexOf('.'), nail = number.lastIndexOf('.');
    if (nail < 0 && tail >= 0) {
        number = number + "." + format.substr(tail + 1, 1);
        nail = number.lastIndexOf('.');
    }
    tail = tail > -1 && nail > -1 ? format.substr(tail) : '';
    var numtail = number.substr(number.indexOf(".") ) ;
    if(tail.length > 0 && dp !== undefined && dp > 0) {
        tail = tail.substr(0, dp + 1);
        var tails = tail.split(''), ntail = "", canPop = true;
        for (var i = 1; i < tails.length; i++) {
            if ((tails[i] == '#' || tails[i].match(/([0-9])/g)) && numtail.length > i) {
                ntail += numtail.substr(i, 1);                    
            }
            else if(tails[i] == '#') {
                ntail += '0';
            }
            else {
                ntail += tails[i];
            }
        }
        var ttail = ntail.split(''), ptail = tail.substr(1).split('');
        for(var i = ttail.length - 1; i > -1; i--){
            if (ptail[i] == '#' && canPop && (ttail[i] == '0' || ttail[i] == '#')) {
                ntail = ntail.substr(0, ntail.length - 1);
            }
            else {
                canPop = false;
            }
        }
        if (ntail.length > 0) {
            tail = "." + ntail;
        }
        else {
            tail = "";   
        }
    }
    number = number.replace(/\..*|[^0-9]/g,'').split('');
    format = format.replace(/\..*/g,'').split('');
    for(var i = format.length - 1; i > -1; i--){
        if(format[i] == '#') {
            format[i]=number.pop()
        }
    }
    number = minus + number.join('') + format.join('') + tail;
    return number;
}

function log(m) {
    div.prepend(m + "<br/>");
}

Friday, November 14, 2014

Spring MVC custom body tag library example


Create two java file with following contents:

package com.pkm.maven.tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyTagOne extends BodyTagSupport {
    private int mTimes = 0;
    private BodyContent mBodyContent;
    
    public void setTimes(int pTimes) {
        mTimes = pTimes;
    }
    
    @Override
    public void setBodyContent(BodyContent pBodyContent) {
        mBodyContent = pBodyContent;
    }
    
    @Override
    public int doStartTag() throws JspException {
        if (mTimes >= 1) {
            return EVAL_BODY_TAG;
        } else {
            return SKIP_BODY;
        }
    }
    
    @Override
    public int doAfterBody() throws JspException {
        if (mTimes > 1) {
            mTimes--;
            return EVAL_BODY_TAG;
        } else {
            return SKIP_BODY;
        }
    }

    
    @Override
    public int doEndTag() throws JspException {
        try {
            if (mBodyContent != null) {
                mBodyContent.writeOut(mBodyContent.getEnclosingWriter());
            }
        } catch (Exception pIOEx) {
            throw new JspException("Error: " + pIOEx.getMessage());
        }
        return EVAL_PAGE;
    }
}





package com.pkm.maven.tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyTagTwo extends BodyTagSupport {    
    @Override
    public int doAfterBody() throws JspException {
        try {
            BodyContent bc = getBodyContent();
            String body = bc.getString();
            JspWriter out = bc.getEnclosingWriter();
            if (body != null) {
                body = body.substring(0, 1).toUpperCase() + body.substring(1);
                out.print(body);
            }
        } 
        catch (Exception ioe) {
            throw new JspException("Error: " + ioe.getMessage());
        }
        return SKIP_BODY;
    }
}

Create the tag library descriptor (TLD) under WEB-INF folder suppose named: "UiTabLib.tld":

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
         version="2.0">
 
     <tlib-version>1.0</tlib-version>
     <short-name>Ui Tab Library</short-name>
     <uri>UiTabLib</uri>
 
     <tag>
        <name>loopText</name>
        <tag-class>com.pkm.maven.tag.BodyTagOne</tag-class>
        <body-content>JSP</body-content>
        <info>This Tag Displayes given text multiple times</info>
        <attribute>
            <name>times</name>
            <required>true</required>
            <description>Provide number of times the text will be repeated</description>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
     <tag>
        <name>capitalize</name>
        <tag-class>com.pkm.maven.tag.BodyTagTwo</tag-class>
        <body-content>JSP</body-content>
        <info>This Tag Displays given string to be capitalized</info>
    </tag>
</taglib>

Reference & use the tag library:

<p>
    Body Tag Example: <br/>
    <% Integer counter = 1; %>
    <UiTabLib:loopText times="10">
        Counter: <%= (counter++) %><br/>
    </UiTabLib:loopText>
   <%= counter %>
</p>
<p>
    String capitalize (text to be capitalized): 
    <UiTabLib:capitalize>text to be capitalized</UiTabLib:capitalize>
</p>

Output would be like this:

Body Tag Example: 
Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
Counter: 6
Counter: 7
Counter: 8
Counter: 9
Counter: 10
11
String capitalize (text to be capitalized): Text to be capitalized

Spring MVC simple custom tag library example

Create a java file with following contents:

package com.pkm.maven.tag;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class NewDateTag extends SimpleTagSupport {
    private String prefix;
 
    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }
    
    @Override
    public void doTag() throws JspException, IOException {
        final JspWriter writer = getJspContext().getOut();
        String pattern = "dd/MM/yyyy H:m:s";
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        if (prefix != null) {
            writer.print(prefix + " ");
        }
        writer.print(format.format(new Date()));
    }
}

Create the tag library descriptor (TLD) under WEB-INF folder suppose named: "UiTabLib.tld":

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
         version="2.0">
 
     <tlib-version>1.0</tlib-version>
     <short-name>Ui Tab Library</short-name>
     <uri>UiTabLib</uri>
  
     <tag>
         <name>newDate</name>
         <tag-class>com.pkm.maven.tag.NewDateTag</tag-class>
         <body-content>empty</body-content>
         <attribute>
             <name>prefix</name>
             <type>java.lang.String</type>
             <required>false</required>
             <rtexprvalue>true</rtexprvalue>
         </attribute>
     </tag>
</taglib>

Reference & use the tag library:

<%@taglib prefix="UiTabLib" uri="UiTabLib" %>

<p>New Date Tag Lib Output: <UiTabLib:newDate/></p>
<p>New Date Tag Lib Output: <UiTabLib:newDate prefix="Prefix"/></p>

Output would be like this:

New Date Tag Lib Output: 14/11/2014 18:25:12
New Date Tag Lib Output: Prefix 14/11/2014 18:25:12

Saturday, October 11, 2014

HANDLING CUSTOM ERROR PAGES IN TOMCAT WITH SPRING MVC

Download full source code from here
web.xml
<error-page>
    <location>/error.jsp</location>
</error-page>
Create a file named 'error.jsp' under 'WEB-INF' with following contents. This jsp file will redirect to error404 action under error controller.
<!DOCTYPE html>
<%@taglib prefix="UiTabLib" uri="UiTabLib" %>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="REFRESH" content="0;url=<UiTabLib:contextPath/>error/error404.htm?<UiTabLib:logError 

request="${requestScope}"/>">
    </head>
    <body>
        &nbsp;
    </body>
</html>
ErrorController.java
package com.pkm.maven.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class ErrorController extends MultiActionController {
    public ModelAndView error404(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setStatus( HttpServletResponse.SC_BAD_REQUEST  );
        String statusCode = request.getParameter("status_code");
        String exception = request.getParameter("exception");
        String requestUri = request.getParameter("request_uri");
        if (requestUri == null) {
            requestUri = "Unknown";
        }
  
        ModelAndView view = new ModelAndView("error/error404");
        view.addObject("statusCode", statusCode);
        view.addObject("exception", exception);
        view.addObject("requestUri", requestUri);
        
        return view; 
    }
}
Create a file named 'error404.jsp' under 'WEB-INF/jsp/error/' folder with following content:
<div>Request URI: ${requestUri}</div>
<div>Status Code: ${statusCode}</div>
<div>Exception: ${exception}</div>


Grail's Create Or Change Database Connection Manually Or Run-time | Using multiple data-sources in a Grail's project | Grail's Multiple Data Sources | Grail's multi tenant data-sources

In src/groovy, create a groovy class named 'UserHolder' with following contents:


package a.b.c

/**
 * Created by pritom on 14/08/2014.
 */
class UserHolder {
    public static Integer DEFAULT = 1;
    private static final ThreadLocal contextHolder = new ThreadLocal();
    public static String DS_PREFIX = "dataSource_";
    public static String DS_POSTFIX = "User";

    static void setEnvironment(Map environment) {
        contextHolder.set(environment);
    }

    static getEnvironment() {
        return contextHolder.get();
    }

    static void clear() {
        contextHolder.remove();
    }
}

Also create a groovy class named 'SwitchableDataSource' in src/groovy with following contents:


package a.b.c

import grails.util.Holders
import org.springframework.context.ApplicationContext
import org.springframework.jdbc.datasource.DriverManagerDataSource
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource

import javax.sql.DataSource

/**
 * Created by pritom on 14/08/2014.
 */
class SwitchableDataSource extends AbstractRoutingDataSource {
    def applicationContext

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext
    }

    protected DataSource determineTargetDataSource() {
        def user = UserHolder.getEnvironment();
        try {
            DriverManagerDataSource ds = super.determineTargetDataSource();
            return ds;
        }
        catch (Exception ex) {
            println "--->Error:: ${ex.getMessage()}";
            try {
                def ga = Holders.getGrailsApplication();
                String beanFullName = UserHolder.DS_PREFIX + user.id + UserHolder.DS_POSTFIX;
                if(user && user.id && ga.mainContext.containsBean( beanFullName ) ) {
                    println "Using data source: '${beanFullName}'";
                    return ga.mainContext.getBean(beanFullName);
                }
            }
            catch (Exception ex2) {
                println "--->Error:: ${ex2.getMessage()}";
            }
        }
    }

    @Override
    protected Object determineCurrentLookupKey() {
        def user = UserHolder.getEnvironment();
        return user?.id ?: UserHolder.DEFAULT;
    }

    @Override
    public void setTargetDataSources(Map<Object, Object> targetDataSources) {
        super.setTargetDataSources(targetDataSources);
    }
}

Edit resource.groovy file under grails-app/conf/spring folder:


import a.b.c.SwitchableDataSource
import a.b.c.UserHolder
import org.springframework.jdbc.datasource.DriverManagerDataSource

// Place your Spring DSL code here
beans = {
    parentDataSource(DriverManagerDataSource) { bean ->
        bean.'abstract' = true;
        driverClassName = 'com.mysql.jdbc.Driver'
        username = "root"
    }

    "rootDataSource"(DriverManagerDataSource) { bean ->
        bean.parent = parentDataSource;
        bean.scope = 'prototype';
        url = "jdbc:mysql://localhost/user${UserHolder.DEFAULT}?useUnicode=yes&characterEncoding=UTF-8";
        username = "root"
    }

    def dataSources = [:]
    dataSources[UserHolder.DEFAULT] = ref("rootDataSource");

    dataSource(SwitchableDataSource) {
        targetDataSources = dataSources
    }
}

Now create another groovy class named 'DataSourceService' to bind datasource to your project dynamically/runtime with following contents:


package a.b.c

import grails.spring.BeanBuilder
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.springframework.beans.BeansException
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.context.support.GenericApplicationContext

/**
 * Created by pritom on 14/08/2014.
 */
class DataSourceService implements ApplicationContextAware {
    ApplicationContext applicationContext;
    public GrailsApplication grailsApplication;

    @Override
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * Add new bean to system
     * @param beanName
     * @param dsurl
     * @param uid
     * @param pwd
     * @return
     */
    def registerBean( String beanName, String dsurl, String uid, String pwd ) {
        String beanFullName = UserHolder.DS_PREFIX + beanName + UserHolder.DS_POSTFIX;
        if( !applicationContext.containsBean( beanFullName ) ) {
            def bb = new BeanBuilder()
            bb.beans {
                "$beanFullName" { bean ->
                    bean.parent = ref('parentDataSource');
                    bean.scope = 'prototype';
                    url = dsurl;
                    username = uid
                    password = pwd
                }
            }
            bb.registerBeans( applicationContext );

            println "Added $beanFullName"
        }
        else {
            println "Already got a bean called $beanFullName"
        }
    }

    /**
     * Remove bean from system
     * @param beanName
     * @return
     */
    def deRegisterBean( String beanName ) {
        if( applicationContext.containsBean( beanName ) ) {
            (applicationContext as GenericApplicationContext).removeBeanDefinition( beanName )
            println "Removed $beanName"
        }
        else {
            println "Trying to deRegister a bean $beanName that I don't know about"
        }
    }
}

Now create a filter in grails-app/filters named 'SecurityFilters' with following contents:


package filters

import a.b.c.UserHolder

class SecurityFilters {

    def filters = {
        all(controller: '*', action: '*') {
            before = {
     /* This line is for specify which user request to handle */
                if (params.int('user')) {
                    UserHolder.setEnvironment([id: params.int('user')]);
                }
            }
            after = { Map model ->

            }
            afterView = { Exception e ->

            }
        }
    }
}

Example of adding a new datasource to system:


DataSourceService dataSourceService = new DataSourceService();
dataSourceService.setApplicationContext(grailsApplication.mainContext);
dataSourceService.grailsApplication = grailsApplication;
dataSourceService.registerBean(params.user, "jdbc:mysql://localhost/user${params.user}?useUnicode=yes&characterEncoding=UTF-8", "root", "");

Suppose params.user = 3 here.

That's it Download code