Monday, December 9, 2013

Reading i18n messages from the database with Grails

At first create a model class:


package com.locale.messaging

class Message {
    String code
    Locale locale
    String text

    static constraints = {
        code(unique: ["locale"])
    }

    static mapping = {
        version(false);
    }
}

Then implement a class that extends the org.springframework.context.support.AbstractMessageSource class. In the example below I am using simple GORM finders to lookup a message using the code and locale


package com.locale.messaging

import com.locale.messaging.Message
import net.sf.ehcache.Ehcache
import org.springframework.context.support.AbstractMessageSource
import net.sf.ehcache.Element;
import java.text.MessageFormat

/**
 * Created with IntelliJ IDEA.
 * User: pritom
 * Date: 9/12/13
 * Time: 9:09 AM
 * To change this template use File | Settings | File Templates.
 */
class DatabaseMessageSource extends AbstractMessageSource {
    Ehcache messageCache
    def messageBundleMessageSource

    @Override
    protected MessageFormat resolveCode(String code, Locale locale) {
        def key = "${code}_${locale.language}_${locale.country}_${locale.variant}";
        def format = messageCache.get(key)?.value;
        if (!format) {
            Message message = Message.findByCodeAndLocale(code, locale);
            if (message) {
                format = new MessageFormat(message.text, message.locale);
            } else {
                format = messageBundleMessageSource.resolveCode(code, locale);
            }
            messageCache.put(new Element(key, format))
        } else {
            format = (MessageFormat) format;
        }
        return format;
    }
}

Then configure an appropriate cache bean (I'm using Ehcache) in Spring and wire it into your MessageSource in grails-app/conf/spring/resources.groovy file:

import com.bitmascot.util.DatabaseMessageSource
import org.springframework.cache.ehcache.EhCacheFactoryBean

// Place your Spring DSL code here
beans = {
    messageCache(EhCacheFactoryBean) {
        eternal = false;
        timeToIdle = 5000;
    }
    messageSource(DatabaseMessageSource) {
        messageCache = messageCache
        messageBundleMessageSource = ref("messageBundleMessageSource")
    }

    messageBundleMessageSource(org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource) {
        basenames = "grails-app/i18n/messages"
    }
}

http://graemerocher.blogspot.com/2010/04/reading-i18n-messages-from-database.html

Sunday, December 8, 2013

How to Set up a Foreign Key Constraint in MySQL

The following is a simple example that illustrates Foreign Key constraints:

Creating a table for manager:
CREATE TABLE manager (id integer primary key auto_increment, name text) ENGINE=InnoDB;

Creating a table for club and creating a foreign key constraint for manager_id with key 'manager_id_reference':
CREATE TABLE club (id integer primary key auto_increment, is_accessible char, manager_id integer NOT NULL) ENGINE=InnoDB;
ALTER TABLE club ADD CONSTRAINT manager_id_reference FOREIGN KEY(manager_id) REFERENCES manager (id);

Inserting some managers:
INSERT INTO manager(name) VALUES('Pritom');
INSERT INTO manager(name) VALUES('Kumar');

Inserting some clubs:
INSERT INTO club(is_accessible, manager_id) VALUES(true, 1);
INSERT INTO club(is_accessible, manager_id) VALUES(false, 2);

Let see manager table data (SELECT * FROM manager):
ID NAME
1 Pritom
2 Kumar

Let see club table data (SELECT * FROM club):
ID IS_ACCESSIBLE MANAGER_ID
1 1 1
2 0 2
Let see manager table structure (DESCRIBE manager):
FIELD TYPE NULL KEY DEFAULT EXTRA
id int(11) NO PRI (null) auto_increment
name text YES (null)
Let see club table structure (DESCRIBE club):
FIELD TYPE NULL KEY DEFAULT EXTRA
id int(11) NO PRI (null) auto_increment
is_accessible char(1) YES (null)
manager_id int(11) NO MUL (null)

Now try to delete manager:
DELETE FROM USER WHERE id = 1;

will error as:
Schema Creation Failed: Cannot delete or update a parent row: a foreign key constraint fails (`db_2_8d4a1`.`club`, CONSTRAINT `manager_id_reference` FOREIGN KEY (`manager_id`) REFERENCES `manager` (`id`)):

This happens because the data in the manager table depends on the data in the club table.

Full sqlFiddle

Getting Request , Response & ServletContext in the Grails service class

import org.codehaus.groovy.grails.web.util.WebUtils;

Getting current request object:
def request = WebUtils.retrieveGrailsWebRequest().getCurrentRequest();

Getting response object:
def response = WebUtils.retrieveGrailsWebRequest().getCurrentResponse();

Getting servletContext object:
def servletContext = WebUtils.retrieveGrailsWebRequest().getServletContext();

Thursday, December 5, 2013

POSTing json data with php cURL


<?php
$params = array(
    "id" => 1,
    "name" => "Pritom Kumar Mondal"
);
$param = json_encode($params);
$ch   = curl_init("http://localhost/api_server/user");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($param))
);
$response = curl_exec($ch);
print_r($response);
?>

Wednesday, December 4, 2013

mysql date format

The DATE_FORMAT() function is used to display date/time data in different formats.

Syntax

DATE_FORMAT(date,format)
Where date is a valid date and format specifies the output format for the date/time.
The formats that can be used are from http://www.w3schools.com/sql/func_date_format.asp:

Format Description
%aAbbreviated weekday name
%bAbbreviated month name
%cMonth, numeric
%DDay of month with English suffix
%dDay of month, numeric (00-31)
%eDay of month, numeric (0-31)
%fMicroseconds
%HHour (00-23)
%hHour (01-12)
%IHour (01-12)
%iMinutes, numeric (00-59)
%jDay of year (001-366)
%kHour (0-23)
%lHour (1-12)
%MMonth name
%mMonth, numeric (00-12)
%pAM or PM
%rTime, 12-hour (hh:mm:ss AM or PM)
%SSeconds (00-59)
%sSeconds (00-59)
%TTime, 24-hour (hh:mm:ss)
%UWeek (00-53) where Sunday is the first day of week
%uWeek (00-53) where Monday is the first day of week
%VWeek (01-53) where Sunday is the first day of week, used with %X
%vWeek (01-53) where Monday is the first day of week, used with %x
%WWeekday name
%wDay of the week (0=Sunday, 6=Saturday)
%XYear of the week where Sunday is the first day of week, four digits, used with %V
%xYear of the week where Monday is the first day of week, four digits, used with %v
%YYear, four digits
%yYear, two digits

Examples in fiddle:

http://sqlfiddle.com/#!2/ccc08/3
















Tuesday, December 3, 2013

Avoid ConcurrentModificationException when using an Java Iterator

Lets explore this scenario with the following example:
First see two methods and then see last two methods.
For first two methods, used simple arraylist and hashmap, so concurrent exception occurs.
But for the later two methods, used copy on write arraylist and concurrent hashmap, so no problem with the last two methods.

package pritom;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: pritom
 * Date: 3/12/13
 * Time: 4:04 PM
 * To change this template use File | Settings | File Templates.
 */
public class ConcurrentModification {
    public static void main(String[] args) {
        ConcurrentModification.concurrentModificationList();
        ConcurrentModification.concurrentModificationHashMap();
        ConcurrentModification.concurrentModificationConcurrentList();
        ConcurrentModification.concurrentModificationConcurrentHashMap();
    }

    private static void concurrentModificationList() {
        try {
            List<String> myDataList = new ArrayList<String>();
            myDataList.add("1");
            myDataList.add("2");
            myDataList.add("3");
            myDataList.add("4");

            System.out.println("Deleting from List: ");
            for (Iterator it = myDataList.iterator(); it.hasNext();) {
                String myObject = (String) it.next();
                if(myObject.equalsIgnoreCase("2") || myObject.equalsIgnoreCase("4")) {
                    System.out.println("Deleting: " + myObject);
                    myDataList.remove(myObject);
                } else {
                    System.out.println("Not deleting: " + myObject);
                }
            }

            System.out.println("After deleting from List: ");
            for (Iterator it = myDataList.iterator(); it.hasNext();) {
                String myObject = (String) it.next();
                System.out.println("Remaining: " + myObject);
            }
        } catch (Throwable ex) {
            System.out.println("***** Deleting from List error: " + ex.toString() + " *****");
        }
    }

    private static void concurrentModificationHashMap() {
        try {
            Map<String, String> myDataList = new HashMap<String, String>();
            myDataList.put("0", "00");
            myDataList.put("1", "11");
            myDataList.put("2", "22");
            myDataList.put("3", "33");

            System.out.println("\n\nDeleting from Map: ");
            for (Iterator it = myDataList.keySet().iterator(); it.hasNext();) {
                String key = (String) it.next();
                if(key.equalsIgnoreCase("2") || key.equalsIgnoreCase("4")) {
                    System.out.println("Deleting: " + key + " = " + myDataList.get(key));
                    myDataList.remove(key);
                } else {
                    System.out.println("Not deleting: " + key + " = " + myDataList.get(key));
                }
            }

            System.out.println("After deleting from Map: ");
            for (Iterator it = myDataList.keySet().iterator(); it.hasNext();) {
                String key = (String) it.next();
                System.out.println("Remaining: " + key + " = " + myDataList.get(key));
            }
        } catch (Throwable ex) {
            System.out.println("***** Deleting from Map error: " + ex.toString() + " *****\n\n");
        }
    }

    private static void concurrentModificationConcurrentList() {
        try {
            List<String> myDataList = new CopyOnWriteArrayList<String>();
            myDataList.add("1");
            myDataList.add("2");
            myDataList.add("3");
            myDataList.add("4");

            System.out.println("\n\nDeleting from Concurrent List: ");
            for (Iterator it = myDataList.iterator(); it.hasNext();) {
                String myObject = (String) it.next();
                if(myObject.equalsIgnoreCase("2") || myObject.equalsIgnoreCase("4")) {
                    System.out.println("Deleting: " + myObject);
                    myDataList.remove(myObject);
                    myDataList.add("55");
                } else {
                    System.out.println("Not deleting: " + myObject);
                }
            }

            System.out.println("After deleting from Concurrent List: ");
            for (Iterator it = myDataList.iterator(); it.hasNext();) {
                String myObject = (String) it.next();
                System.out.println("Remaining: " + myObject);
            }
        } catch (Throwable ex) {
            System.out.println("***** Deleting from Concurrent List error: " + ex.toString() + " *****");
        }
    }

    private static void concurrentModificationConcurrentHashMap() {
        try {
            Map<String, String> myDataList = new ConcurrentHashMap<String, String>();
            myDataList.put("1", "11");
            myDataList.put("2", "22");
            myDataList.put("3", "33");
            myDataList.put("4", "44");

            System.out.println("\n\nDeleting from Concurrent Map: ");
            for (Iterator it = myDataList.keySet().iterator(); it.hasNext();) {
                String key = (String) it.next();
                if(key.equalsIgnoreCase("2") || key.equalsIgnoreCase("4")) {
                    System.out.println("Deleting: " + key + " = " + myDataList.get(key));
                    myDataList.remove(key);
                    System.out.println("Adding: 5 = 55");
                    myDataList.put("5", "55");
                } else {
                    System.out.println("Not deleting: " + key + " = " + myDataList.get(key));
                }
            }

            System.out.println("After deleting from Concurrent Map: ");
            for (Iterator it = myDataList.keySet().iterator(); it.hasNext();) {
                String key = (String) it.next();
                System.out.println("Remaining: " + key + " = " + myDataList.get(key));
            }
        } catch (Throwable ex) {
            System.out.println("***** Deleting from Concurrent Map error: " + ex.toString() + " *****\n\n");
        }
    }
}

And see the output


Deleting from List: 
Not deleting: 1
Deleting: 2
***** Deleting from List error: java.util.ConcurrentModificationException *****


Deleting from Map: 
Not deleting: 3 = 33
Deleting: 2 = 22
***** Deleting from Map error: java.util.ConcurrentModificationException *****




Deleting from Concurrent List: 
Not deleting: 1
Deleting: 2
Not deleting: 3
Deleting: 4
After deleting from Concurrent List: 
Remaining: 1
Remaining: 3
Remaining: 55
Remaining: 55


Deleting from Concurrent Map: 
Not deleting: 1 = 11
Not deleting: 3 = 33
Deleting: 4 = 44
Adding: 5 = 55
Deleting: 2 = 22
Adding: 5 = 55
After deleting from Concurrent Map: 
Remaining: 1 = 11
Remaining: 5 = 55
Remaining: 3 = 33

To Avoid ConcurrentModificationException in multi-threaded environment (first two methods):
1. You can convert the list to an array and then iterate on the array. This approach works well for small or medium size list but if the list is large then it will affect the performance a lot.
2. You can lock the list while iterating by putting it in a synchronized block. This approach is not recommended because it will cease the benefits of multithreading.
3. If you are using JDK1.5 or higher then you can use ConcurrentHashMap and CopyOnWriteArrayList classes. It is the recommended approach.

From the above example its clear that (last two methods):
1. Concurrent Collection classes can be modified avoiding ConcurrentModificationException.
2. In case of CopyOnWriteArrayList, iterator doesn’t accomodate the changes in the list and works on the original list.
3. In case of ConcurrentHashMap, the behavior is not always the same.

Monday, December 2, 2013

Removing invalid characters from XML

XML as you would know essentially consists of markup tags and character data. The markup tags are > (greater than), < (less than), ' (single quote), " (double quote) and & (ampersand). Character data which appears inside text nodes or in attributes could be anything, any character in any language.
But not all Unicode characters are fit to be included in XML as character data. There are two specs that one needs to refer to understand this
  1. http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
  2. http://www.w3.org/TR/2000/REC-xml-20001006#syntax
The following Java code is an implementation of these rules. It essentially removes all these illegal Unicode characters.

private static String removeInvalidXMLCharacters(String xmlString) {
    StringBuilder out = new StringBuilder();
    int codePoint;
    int i = 0;
    while (i < xmlString.length())
    {
        // This is the unicode code of the character.
        codePoint = xmlString.codePointAt(i);
        if ((codePoint == 0x9) ||
                (codePoint == 0xA) ||
                (codePoint == 0xD) ||
                ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
                ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
                ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)))
        {
            out.append(Character.toChars(codePoint));
        }
        i += Character.charCount(codePoint);
    }
    return out.toString();
}