Popular Posts
ADD ... THEN ... UNTIL ... data: begin of SERIES, N1 type I value 10, N2 type I value 20, N3 type I value 30, N4 type I value 40, ... Join related table and count rows or sum sql server 2005 count rows: SELECT * FROM Table1 LEFT JOIN     (SELECT Level1ID, COUNT(Level2ID) AS Total FROM Table2 GROUP BY Level1ID) AS... Remove file not in list
Stats
Integration config for spring & hibernate
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.prhythm.spring.web.controller"/>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
        <property name="url" value="jdbc:hsqldb:mem:test"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="com.prhythm.spring.web.model"/>
        <!--<property name="annotatedClasses">-->
            <!--<list>-->
                <!--<value>com.prhythm.spring.web.model.Employee</value>-->
            <!--</list>-->
        <!--</property>-->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager"
          class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

</beans>
Wrong text encoding while Jsoup parse document

While page encoding is different with content type encoding declaration. Jsoup will get wrong text decode content. To avoid this problem, Assign a correct text encoding will be required.

Connection connection = Jsoup.connect(requestUrl)
        .data("type", "1")
        .data("searchKeyUID", searchKeyUID)
        .timeout(timeout)
        .method(Connection.Method.GET);

Connection.Response response = connection.execute();
Document document = Jsoup.parse(new ByteArrayInputStream(response.bodyAsBytes()), "UTF-8", requestUrl);
Group data on SQLite

Schema

CREATE TABLE invoice
(
    Id INTEGER PRIMARY KEY,
    code TEXT,
    dropped INTEGER,
    due_date INTEGER,
    paid INTEGER,
    due_date2 TEXT
);

Initial data

INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (1, 'IMSS', 0, 1407384129647, 0, '2014-08-07 04:02:09');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (2, 'Deep Discovery family', 0, 1407346684736, 0, '2014-08-06 17:38:04');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (3, 'TMMS​', 1, 1407375568242, 0, '2014-08-07 01:39:28');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (4, 'TMS family​', 0, 1407374437084, 1, '2014-08-07 01:20:37');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (5, 'SafeSync', 0, 1407358168347, 1, '2014-08-06 20:49:28');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (6, 'TMVMS​', 0, 1407350693881, 0, '2014-08-06 18:44:53');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (7, 'TMS family​', 0, 1407372590354, 0, '2014-08-07 00:49:50');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (8, 'IMSVA', 0, 1407344495046, 0, '2014-08-06 17:01:35');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (9, 'Other', 0, 1407351210774, 0, '2014-08-06 18:53:30');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (10, 'Deep Discovery family', 0, 1407372667906, 0, '2014-08-07 00:51:07');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (11, 'IMSVA', 1, 1407365934950, 1, '2014-08-06 22:58:54');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (12, 'PSP', 1, 1407382557767, 1, '2014-08-07 03:35:57');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (13, 'SecureCloud​', 0, 1407371609679, 0, '2014-08-07 00:33:29');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (14, 'NVWE​', 0, 1407383088966, 0, '2014-08-07 03:44:48');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (15, 'ESE', 1, 1407360299869, 1, '2014-08-06 21:24:59');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (16, 'IMSVA', 0, 1407377397832, 0, '2014-08-07 02:09:57');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (17, 'IWSVA​', 0, 1407366067348, 1, '2014-08-06 23:01:07');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (18, 'TMS family​', 1, 1407351067728, 0, '2014-08-06 18:51:07');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (19, 'OSCE​', 0, 1407345046895, 0, '2014-08-06 17:10:46');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (20, 'TIM​', 0, 1407363640638, 1, '2014-08-06 22:20:40');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (21, 'CSS​', 1, 1407330238874, 0, '2014-08-06 13:03:58');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (22, 'TMPS​', 1, 1407321708684, 1, '2014-08-06 10:41:48');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (23, 'TMS family​', 1, 1407319881608, 0, '2014-08-06 10:11:21');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (24, 'SafeSync', 1, 1407306547713, 0, '2014-08-06 06:29:07');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (25, 'ESDP', 0, 1407298566126, 0, '2014-08-06 04:16:06');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (26, 'CSS​', 0, 1407282477671, 0, '2014-08-05 23:47:57');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (27, 'TMMS​', 1, 1407240200509, 1, '2014-08-05 12:03:20');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (28, 'Other', 0, 1407218499996, 0, '2014-08-05 06:01:39');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (29, 'ESE', 0, 1407210588362, 0, '2014-08-05 03:49:48');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (30, 'CSS​', 0, 1407207304034, 0, '2014-08-05 02:55:04');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (31, 'TMVMS​', 1, 1407188482248, 0, '2014-08-04 21:41:22');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (32, 'SecureCloud​', 0, 1407155296508, 0, '2014-08-04 12:28:16');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (33, 'TMS family​', 1, 1407136374493, 0, '2014-08-04 07:12:54');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (34, 'ESE', 1, 1407121543307, 1, '2014-08-04 03:05:43');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (35, 'ScanMail', 0, 1407118018107, 0, '2014-08-04 02:06:58');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (36, 'ScanMail', 0, 1407088856291, 0, '2014-08-03 18:00:56');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (37, 'IMSS', 0, 1407059314747, 1, '2014-08-03 09:48:34');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (38, 'OSCE​', 1, 1407027453954, 0, '2014-08-03 00:57:33');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (39, 'Deep Discovery family', 0, 1406995304204, 0, '2014-08-02 16:01:44');
INSERT INTO invoice (Id, code, dropped, due_date, paid, due_date2) VALUES (40, 'Worry-Free', 0, 1406968142441, 0, '2014-08-02 08:29:02');

Group select

select 
  Id, 
  code, 
  (dropped|paid) status, 
  (due_date < 1407200000000) expired, 
  due_date2 
from invoice 
order by 
  paid|dropped, 
  (due_date > 1407200000000), 
  due_date desc

result

android.intent.action.SCREEN_ON & android.intent.action.SCREEN_OFF

First, I've tried create a receiver to receive screen on/off and register receiver on AndroidManifest.xml like below, but unfortunately it does not work.

ScreenReceiver.java
package com.prhythm.training.service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * Created by Bruce on 7/15/2014.
 */
public class ScreenReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("Receiver", String.format("Broadcast action: %s", intent.getAction()));
    }
}
AndroidManifest.xml
<receiver android:name=".service.ScreenReceiver">
    <intent-filter>
        <action android:name="android.intent.action.SCREEN_ON"/>
        <action android:name="android.intent.action.SCREEN_OFF"/>
    </intent-filter>
</receiver>

I's nessary to register screen action receiver by code, so I've change the as

ScreenReceiver.java
package com.prhythm.training.service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * Created by Bruce on 7/15/2014.
 */
public class ScreenReceiver extends BroadcastReceiver {

    public static ScreenReceiver CURRENT;

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("Receiver", String.format("Broadcast action: %s", intent.getAction()));
    }
}
ScreenService.java
package com.prhythm.training.service;

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;

/**
 * Created by Bruce on 7/15/2014.
 */
public class ScreenService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        // Register screen on/off receiver
        if (ScreenReceiver.CURRENT == null) ScreenReceiver.CURRENT = new ScreenReceiver();
        getApplicationContext().registerReceiver(ScreenReceiver.CURRENT, new IntentFilter(Intent.ACTION_SCREEN_ON));
        getApplicationContext().registerReceiver(ScreenReceiver.CURRENT, new IntentFilter(Intent.ACTION_SCREEN_OFF));
    }
}

Then, start this service is required

startService(new Intent(this, ScreenService.class));
Enable SSL connection for Jsoup
import org.jsoup.Connection;
import org.jsoup.Jsoup;

import javax.net.ssl.*;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class TaipeiWater {
    
    final static String requestUrl = "https://somewhere.com/target.jsp";

    public static void enableSSLSocket() throws KeyManagementException, NoSuchAlgorithmException {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, new X509TrustManager[]{new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }}, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
    }

    public static void main(String[] args) throws IOException, NoSuchAlgorithmException, KeyManagementException {
        String bigno = "S";
        String midno = "11";
        String useno = "111111";
        String chkno = "1";

        enableSSLSocket();

        Connection.Response response = Jsoup.connect(requestUrl)
                .data("bigno", bigno)
                .data("midno", midno)
                .data("useno", useno)
                .data("chkno", chkno)
                .userAgent("Mozilla/5.0 (Windows NT 6.2; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0")
                .method(Connection.Method.POST)
                .execute();

        switch (response.statusCode()) {
            case 200:
                doProcess(response.parse());
                break;
            default:
                
                break;
        }
    }

    public static void doProcess(Document document){
        // do something...
    }
}
Register preference change event with PreferenceFragment
public class DevicePreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preference);
    }

    @Override
    public void onResume() {
        super.onResume();
        getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

    }

    @Override
    public void onPause() {
        getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
        super.onPause();
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        Log.d(MainActivity.TAG, String.format("Preference '%s' has been changed.", key));
        if ("pref_track_interval".equals(key)) {
            // do something
        }
    }
}
Set remote respository for Intellij IDEA git integration
  1. Create a new project
  2. VCS -> Import into Version Control -> Create Git Repository... , then select the project path
  3. Open project path, find the config file at hidden subfolder .git
    Edit config file, add following contents at end:
    [remote "origin"]
     url = http://www.yourgitserver.com/repository.git
     fetch = +refs/heads/*:refs/remotes/origin/*
  4. File -> Synchronize
  5. That it! Try commit and push your project
Override Response Content-Type with OutputCache

Response content-type will be set as text/html on OutputCache is assigned, even if there is an assignment inside action.

HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [OutputCache(Duration = 60)]
        public ActionResult NavigationScript()
        {
            Response.ContentType = "application/javascript";
            return View();
        }
    }
}
Result

Custom a attribute and change content type after output cache processed.

ResponseHeaderAttribute.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication1.Filter
{
    public class ResponseHeaderAttribute : ActionFilterAttribute
    {
        public string ContentType { get; set; }
        public System.Text.Encoding ContentEncoding { get; set; }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            if (!string.IsNullOrWhiteSpace(ContentType)) filterContext.HttpContext.Response.ContentType = ContentType;
            if (ContentEncoding != null) filterContext.HttpContext.Response.ContentEncoding = ContentEncoding;
        }
    }
}
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Filter;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [OutputCache(Duration = 60, Order = 1)]
        [ResponseHeader(ContentType = "application/javascript", Order = 2)]
        public ActionResult NavigationScript()
        {
            return View();
        }
    }
}
Result
Session State Locks cause pending requests

In some scenario, while there is a long pending request exist, it may cause other request pending because session data is locked by the first request. Here is a example of session lock.

First I have a controller with default session policy

using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication2.Models;

namespace WebApplication2.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult LongTimeout()
        {
            System.Threading.Thread.Sleep(30000);
            return Json(new { code = 200 }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult ShortTimeout()
        {
            return Json(new { code = 200 }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Captcha()
        {
            var captcha = MathCaptcha.Generate();
            Session["captcha"] = captcha.Answer;

            return File(captcha.GetImageData(ImageFormat.Png), "image/png");
        }
    }
}

And then create another controller that make session state readonly

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication2.Controllers
{
    [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
    public class SessionLessController : Controller
    {
        public ActionResult LongTimeout()
        {
            System.Threading.Thread.Sleep(30000);
            return Json(new {code=200 }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult ShortTimeout()
        {
            return Json(new { code = 200 }, JsonRequestBehavior.AllowGet);
        }
    }
}

Request is pending because the session of first request is locked

After first request completed, other requests will go on

Request won't be block when session state is set as readonly

[Json.net] Convert enum to string
[JsonConverter(typeof(StringEnumConverter))]
public enum Gender
{
    [EnumMember(Value = "man")]
    Male,
    [EnumMember(Value = "woman")]
    Femail,
    [EnumMember(Value = "unknown")]
    Unknown
}