Popular Posts
Enable SSL connection for Jsoup import org.jsoup.Connection; import org.jsoup.Jsoup; import javax.net.ssl.*; import java.io.IOException; import java.security.KeyManagement... JDateField package bruce.lib.swing; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.A... Get files name in batch Windows Batch : get filename using [%%~ni] Linux Shell Script : get filename using [awk, sed] windows sample : rename all *.htm file to ...
Stats
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
}
CORS in Asp.net MVC Web API v2

Step 1.

Install cors from NeGet

Step 2.

Enable cors in config
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace WebSample
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.EnableCors();
        }
    }
}

Step 3

Add cors attribute to your controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
using WebSample.Models;

namespace WebSample.Controllers.Api
{
    public class JobController : ApiController
    {
        [EnableCors(origins: "*", headers: "*", methods: "GET")]
        public Message Get()
        {
            return new Message
            {
                ID = 2,
                Content = "Job"
            };
        }
    }
}

Step 4

Test x-domain request
Math Captcha
public class MathCaptcha
{
    public static MathCaptcha Generate(int degree = 3)
    {
        if (degree < 2) degree = 2;

        var verifier = new MathCaptcha();
        var rdm = new Random(unchecked((int)DateTime.Now.Ticks));
        var nums = new decimal[] {
            rdm.Next(1, (int)Math.Pow(10, degree)),
            rdm.Next(1, (int)Math.Pow(10, degree)),
            rdm.Next(1, (int)Math.Pow(10, degree))
        };
        nums = nums.OrderBy(n => n).ToArray();

        while (true)
        {
            if ((decimal)Math.Pow(10, degree) - 1 <= nums[0] * nums[1])
            {
                nums[2] = Math.Ceiling(nums[2] * (decimal)rdm.NextDouble());
            }
            else if ((decimal)Math.Pow(10, degree - 1) >= nums[0] * nums[1])
            {
                nums[0] = Math.Ceiling(nums[0] * (decimal)(rdm.NextDouble() + 1));
            }
            else
            {
                break;
            }
            nums = nums.OrderBy(n => n).ToArray();
        }

        if (rdm.NextDouble() > 0.5)
        {
            while (degree != Math.Abs(nums[0] * nums[1] + nums[2]).ToString().Length)
            {
                nums[2] = Math.Ceiling(nums[2] * (decimal)rdm.NextDouble());
            }

            if (rdm.NextDouble() > 0.7)
            {
                verifier.Text = string.Format("{0}x{1}+{2}", nums[0], nums[1], nums[2]);
                verifier.Answer = nums[0] * nums[1] + nums[2];
            }
            else
            {
                verifier.Text = string.Format("{2}+{0}x{1}", nums[0], nums[1], nums[2]);
                verifier.Answer = nums[2] + nums[0] * nums[1];
            }
        }
        else
        {
            while (degree != Math.Abs(nums[0] * nums[1] - nums[2]).ToString().Length)
            {
                nums[2] = Math.Ceiling(nums[2] * (decimal)rdm.NextDouble());
            }

            if (nums[0] * nums[1] - nums[2] > 0)
            {
                verifier.Text = string.Format("{0}x{1}-{2}", nums[0], nums[1], nums[2]);
                verifier.Answer = nums[0] * nums[1] - nums[2];
            }
            else
            {
                verifier.Text = string.Format("{2}-{0}x{1}", nums[0], nums[1], nums[2]);
                verifier.Answer = nums[2] - nums[0] * nums[1];
            }
        }

        return verifier;
    }

    public string Text { get; private set; }
    public decimal Answer { get; private set; }

    private MathCaptcha() { }

    public byte[] GetImageData(System.Drawing.Imaging.ImageFormat format)
    {
        var ms = new System.IO.MemoryStream();
        CaptchaImage.Save(ms, format);
        ms.Close();
        return ms.ToArray();
    }

    public Bitmap CaptchaImage
    {
        get
        {
            var w = Text.Length * 13;
            var h = 25;
            var rdm = new Random();
            var bmp = new Bitmap(w, h);
            var graphic = Graphics.FromImage(bmp);
            var font = new Font("Verdana", 14, FontStyle.Italic);

            for (int i = 1; i <= 10; i++)
            {
                graphic.DrawLine(GetPen(i), rdm.Next(w), 0, rdm.Next(w), h);
            }

            graphic.DrawString(Text, font, Brushes.Black, 0, 0);
            for (int i = 0; i <= 50; i++)
            {
                int RandPixelX = rdm.Next(0, w);
                int RandPixelY = rdm.Next(0, h);
                bmp.SetPixel(RandPixelX, RandPixelY, Color.Blue);
            }

            return bmp;
        }
    }

    #region Get brush color
    protected Pen GetPen(int i)
    {
        Pen PenLine = new Pen(Brushes.Red, 1);
        switch (i)
        {
            case 1:
                PenLine = new Pen(Brushes.Red, 1);
                break;
            case 2:
                PenLine = new Pen(Brushes.BlueViolet, 1);
                break;
            case 3:
                PenLine = new Pen(Brushes.GreenYellow, 1);
                break;
            case 4:
                PenLine = new Pen(Brushes.Gold, 1);
                break;
            case 5:
                PenLine = new Pen(Brushes.MediumBlue, 1);
                break;
            case 6:
                PenLine = new Pen(Brushes.MintCream, 1);
                break;
            case 7:
                PenLine = new Pen(Brushes.Pink, 1);
                break;
            case 8:
                PenLine = new Pen(Brushes.Purple, 1);
                break;
            case 9:
                PenLine = new Pen(Brushes.HotPink, 1);
                break;
            case 10:
                PenLine = new Pen(Brushes.Chocolate, 1);
                break;
        }
        return PenLine;
    }
    #endregion
}