<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2225800074603699030</id><updated>2012-02-09T03:07:28.656+07:00</updated><category term='jquery'/><category term='Admin'/><category term='postgresql'/><category term='How To'/><category term='checkstyle'/><category term='Internet'/><category term='javascript'/><category term='java'/><category term='Email'/><category term='jpa'/><category term='swing'/><category term='Linux'/><category term='ajax'/><category term='html'/><category term='Ubuntu'/><category term='playframework'/><category term='Blog'/><title type='text'>Rumahku...</title><subtitle type='html'>sverdianto-blog.blogspot.com</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-49722951647375671</id><published>2011-06-22T18:25:00.012+07:00</published><updated>2011-06-24T23:45:41.329+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java Thumbnail Generator</title><content type='html'>I am currently working on a Java project that need a good image thumbnail generator. I have been searching trough the search engine and found a lot of Java code that uses &lt;a href="http://java.sun.com/javase/technologies/desktop/media/jai/"&gt;Java Advanced Imaging (JAI)&lt;/a&gt; library for image manipulation (scaling, hinting, etc). Most of it looks messy :D but I found a quite good lib, well coded Groovy class (What, Groovy? - Hell, now I remember I used this before on my Grails based project).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/plugin/image-tools"&gt;ImageTool&lt;/a&gt;, a Grails plugin. I prefer to convert this to Java instead of writing my own library. Here is the original &amp; resulting thumbnail using the library.&lt;br /&gt;&lt;br /&gt;&lt;table border="0"&gt;&lt;tr&gt; &lt;td colspan="3"&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;strong&gt;Original Image :&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-NauUDs1XJAM/TgHn1DVliPI/AAAAAAAAADM/_6Z7NeS3MQ4/s1600/tiger.jpg" imageanchor="1" style=""&gt;&lt;img border="0" height="300" width="400" src="http://1.bp.blogspot.com/-NauUDs1XJAM/TgHn1DVliPI/AAAAAAAAADM/_6Z7NeS3MQ4/s400/tiger.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;strong&gt;Default Thumbnail :&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-wIiAK63e0eo/TgHn-dOzwnI/AAAAAAAAADU/mAWtgx7e7WY/s1600/a.png" imageanchor="1" style=""&gt;&lt;img border="0" height="75" width="100" src="http://4.bp.blogspot.com/-wIiAK63e0eo/TgHn-dOzwnI/AAAAAAAAADU/mAWtgx7e7WY/s400/a.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;strong&gt;High Quality Thumbnail :&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-6lLrAkOFdpQ/TgHoH3w4UzI/AAAAAAAAADc/m-2nCEUX7ho/s1600/b.png" imageanchor="1" style=""&gt;&lt;img border="0" height="75" width="100" src="http://3.bp.blogspot.com/-6lLrAkOFdpQ/TgHoH3w4UzI/AAAAAAAAADc/m-2nCEUX7ho/s400/b.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;strong&gt;Square Thumbnail :&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-zD_ZkvCe9G8/TgS-lmTrkPI/AAAAAAAAADs/hwkgXIjsoA0/s1600/c.png" imageanchor="1" style=""&gt;&lt;img border="0" height="75" width="76" src="http://4.bp.blogspot.com/-zD_ZkvCe9G8/TgS-lmTrkPI/AAAAAAAAADs/hwkgXIjsoA0/s400/c.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Above example show bad &amp; good quality of the thumbnail, you should notice the difference.&lt;br /&gt;&lt;br /&gt;Basically, Groovy run on top of JVM and Groovy also understand Java syntax. So, it is not difficult to convert this to Java. &lt;em&gt;Please note that this require JAI library to be installed (or included)&lt;/em&gt;. Here is the converted source code.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;"&gt;import java.awt.RenderingHints;&lt;br /&gt;import java.io.*;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.awt.image.renderable.*;&lt;br /&gt;import javax.media.jai.*;&lt;br /&gt;import com.sun.media.jai.codec.*;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * &lt;p&gt;A java version of thumbnail generator http://www.grails.org/plugin/image-tools.&lt;/p&gt;*  &lt;br /&gt; * @author sverdianto&lt;br /&gt; * @see http://www.grails.org/plugin/image-tools&lt;br /&gt; * @version 1.0.4&lt;br /&gt; * &lt;br /&gt; */&lt;br /&gt;class ImageTool {&lt;br /&gt;    static Map masks = new HashMap();&lt;br /&gt;    static Map alphas = new HashMap();&lt;br /&gt;&lt;br /&gt;    private RenderedOp original = null;&lt;br /&gt;    private RenderedOp image = null;&lt;br /&gt;    private RenderedOp result = null;&lt;br /&gt;    private RenderedOp alpha = null;&lt;br /&gt;    private RenderedOp mask = null;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Removes the accelaration lib exception &lt;br /&gt;     */&lt;br /&gt;    static {&lt;br /&gt;        System.setProperty("com.sun.media.jai.disableMediaLib", "true");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Should a thumbnail be created only if it will be smaller in size than the&lt;br /&gt;     * current image?&lt;br /&gt;     */&lt;br /&gt;    boolean decreaseOnly = true;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Returns the height for the currently loaded image&lt;br /&gt;     * &lt;br /&gt;     * @return height of the currently loaded image&lt;br /&gt;     */&lt;br /&gt;    public int getHeight() {&lt;br /&gt;        return image.getHeight();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Returns the width for the currently loaded image&lt;br /&gt;     * &lt;br /&gt;     * @return width of the currently loaded image&lt;br /&gt;     */&lt;br /&gt;    public int getWidth() {&lt;br /&gt;        return image.getWidth();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Saves a snapshot of the currently loaded image&lt;br /&gt;     * &lt;br /&gt;     */&lt;br /&gt;    public void saveOriginal() {&lt;br /&gt;        original = (RenderedOp) image.createSnapshot();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Restores a snapshot onto the original image.&lt;br /&gt;     * &lt;br /&gt;     */&lt;br /&gt;    public void restoreOriginal() {&lt;br /&gt;        image = (RenderedOp) original.createSnapshot();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Loads an image from a file.&lt;br /&gt;     * &lt;br /&gt;     * @param file&lt;br /&gt;     *            path to the file from which the image should be loaded&lt;br /&gt;     * @throws IOException&lt;br /&gt;     */&lt;br /&gt;    public void load(String file) throws IOException {&lt;br /&gt;        FileSeekableStream fss = new FileSeekableStream(file);&lt;br /&gt;        image = JAI.create("stream", fss);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Loads a mask from a file and saves it on the cache, indexed by the file&lt;br /&gt;     * name&lt;br /&gt;     * &lt;br /&gt;     * @throws IOException&lt;br /&gt;     */&lt;br /&gt;    public void loadMask(String file) throws IOException {&lt;br /&gt;        mask = (RenderedOp) ImageTool.masks.get(file);&lt;br /&gt;        if (mask == null) {&lt;br /&gt;            FileSeekableStream fss = new FileSeekableStream(file);&lt;br /&gt;            mask = JAI.create("stream", fss);&lt;br /&gt;            masks.put(file, mask);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Loads an alpha mask from a file and saves it on the cache&lt;br /&gt;     * &lt;br /&gt;     * @throws IOException&lt;br /&gt;     */&lt;br /&gt;    public void loadAlpha(String file) throws IOException {&lt;br /&gt;        alpha = (RenderedOp) ImageTool.alphas.get(file);&lt;br /&gt;        if (alpha == null) {&lt;br /&gt;            FileSeekableStream fss = new FileSeekableStream(file);&lt;br /&gt;            alpha = JAI.create("stream", fss);&lt;br /&gt;            alphas.put(file, alpha);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Overwrites the current image with the latest result image obtained.&lt;br /&gt;     */&lt;br /&gt;    public void swapSource() {&lt;br /&gt;        image = result;&lt;br /&gt;        result = null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Loads an image from a byte array.&lt;br /&gt;     * &lt;br /&gt;     * @param bytes&lt;br /&gt;     *            array to be used for image initialization&lt;br /&gt;     * @throws IOException&lt;br /&gt;     */&lt;br /&gt;    public void load(byte[] bytes) throws IOException {&lt;br /&gt;        ByteArraySeekableStream byteStream = new ByteArraySeekableStream(bytes);&lt;br /&gt;        image = JAI.create("stream", byteStream);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Writes the resulting image to a file.&lt;br /&gt;     * &lt;br /&gt;     * @param file&lt;br /&gt;     *            full path where the image should be saved&lt;br /&gt;     * @param type&lt;br /&gt;     *            file type for the image&lt;br /&gt;     * @see &lt;a&lt;br /&gt;     *      href="http://java.sun.com/products/java-media/jai/iio.html"&gt;Possible&lt;br /&gt;     *      JAI encodings&lt;/a&gt;&lt;br /&gt;     */&lt;br /&gt;    public void writeResult(String file, String type) throws IOException {&lt;br /&gt;        FileOutputStream os = new FileOutputStream(file);&lt;br /&gt;        JAI.create("encode", result, os, type, null);&lt;br /&gt;        os.close();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Returns the resulting image as a byte array.&lt;br /&gt;     * &lt;br /&gt;     * @param type&lt;br /&gt;     *            file type for the image&lt;br /&gt;     * @see &lt;a&lt;br /&gt;     *      href="http://java.sun.com/products/java-media/jai/iio.html"&gt;Possible&lt;br /&gt;     *      JAI encodings&lt;/a&gt;&lt;br /&gt;     */&lt;br /&gt;    public byte[] getBytes(String type) throws IOException {&lt;br /&gt;        ByteArrayOutputStream bos = new ByteArrayOutputStream();&lt;br /&gt;        JAI.create("encode", result, bos, type, null);&lt;br /&gt;        return bos.toByteArray();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Creates a thumbnail of a maximum length and stores it in the result image&lt;br /&gt;     * &lt;br /&gt;     * @param edgeLength&lt;br /&gt;     *            Maximum length&lt;br /&gt;     */&lt;br /&gt;    public void thumbnail(float edgeLength) {&lt;br /&gt;        if (getHeight() &lt; edgeLength &amp;&amp; getWidth() &lt; edgeLength &amp;&amp; decreaseOnly) {&lt;br /&gt;            result = image;&lt;br /&gt;        } else {&lt;br /&gt;            boolean tall = (getHeight() &gt; getWidth());&lt;br /&gt;            float modifier = edgeLength&lt;br /&gt;                    / (float) (tall ? getHeight() : getWidth());&lt;br /&gt;            ParameterBlock params = new ParameterBlock();&lt;br /&gt;            params.addSource(image);&lt;br /&gt;            params.add(modifier);// x scale factor&lt;br /&gt;            params.add(modifier);// y scale factor&lt;br /&gt;            params.add(0.0F);// x translate&lt;br /&gt;            params.add(0.0F);// y translate&lt;br /&gt;            params.add(new InterpolationNearest());// interpolation method&lt;br /&gt;            result = JAI.create("scale", params);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * This method creates a thumbnail of the maxWidth and maxHeight it takes as&lt;br /&gt;     * a parameter&lt;br /&gt;     * &lt;br /&gt;     * Example : Calling the method thumnailSpecial(640, 480, 1, 1) will never&lt;br /&gt;     * produce images larger than 640 on the width, and never larger than 480 on&lt;br /&gt;     * the height and use InterpolationBilinear(8) and scale&lt;br /&gt;     * &lt;br /&gt;     * @param maxWidth&lt;br /&gt;     *            The maximum width the thumbnail is allowed to have&lt;br /&gt;     * &lt;br /&gt;     * @param maxHeigth&lt;br /&gt;     *            The maximum height the thumbnail is allowed to have&lt;br /&gt;     * &lt;br /&gt;     * @param interPolationType&lt;br /&gt;     *            Is for you to choose what interpolation you wish to use 1 :&lt;br /&gt;     *            InterpolationBilinear(8) // Produces good image quality with&lt;br /&gt;     *            smaller image size(byte) then the other two 2 :&lt;br /&gt;     *            InterpolationBicubic(8) // Supposed to produce better than&lt;br /&gt;     *            above, but also larger size(byte) 3 : InterpolationBicubic2(8)&lt;br /&gt;     *            // Supposed to produce the best of the three, but also largest&lt;br /&gt;     *            size(byte)&lt;br /&gt;     * &lt;br /&gt;     * @param renderingType&lt;br /&gt;     *            Too choose the rendering type 1: Uses scale // Better on&lt;br /&gt;     *            larger thumbnails 2: Uses SubsampleAverage // Produces clearer&lt;br /&gt;     *            images when it comes to really small thumbnail e.g 80x60&lt;br /&gt;     */&lt;br /&gt;    public void thumbnailSpecial(float maxWidth, float maxHeight,&lt;br /&gt;            int interPolationType, int renderingType) {&lt;br /&gt;        if (getHeight() &lt;= maxHeight &amp;&amp; getWidth() &lt;= maxWidth) {&lt;br /&gt;            /**&lt;br /&gt;             * Don't change, keep it as it is, even though one might loose out&lt;br /&gt;             * on the compression included below (not sure)&lt;br /&gt;             */&lt;br /&gt;            result = image;&lt;br /&gt;        } else {&lt;br /&gt;            boolean tall = (getHeight() * (maxWidth / maxHeight) &gt; getWidth());&lt;br /&gt;            float modifier = maxWidth&lt;br /&gt;                    / (float) (tall ? (getHeight() * (maxWidth / maxHeight))&lt;br /&gt;                            : getWidth());&lt;br /&gt;            ParameterBlock params = new ParameterBlock();&lt;br /&gt;            params.addSource(image);&lt;br /&gt;&lt;br /&gt;            /**&lt;br /&gt;             * Had to do this because of that the different rendering options&lt;br /&gt;             * require either float or double&lt;br /&gt;             */&lt;br /&gt;            switch (renderingType) {&lt;br /&gt;            case 1:&lt;br /&gt;                params.add(modifier);// x scale factor&lt;br /&gt;                params.add(modifier);// y scale factor&lt;br /&gt;                break;&lt;br /&gt;            case 2:&lt;br /&gt;                params.add((double) modifier);// x scale factor&lt;br /&gt;                params.add((double) modifier);// y scale factor&lt;br /&gt;                break;&lt;br /&gt;            default:&lt;br /&gt;                params.add(modifier);// x scale factor&lt;br /&gt;                params.add(modifier);// y scale factor&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            params.add(0.0F);// x translate&lt;br /&gt;            params.add(0.0F);// y translate&lt;br /&gt;            switch (interPolationType) {&lt;br /&gt;            case 1:&lt;br /&gt;                params.add(new InterpolationBilinear(8));&lt;br /&gt;                break; // Produces good image quality with smaller image&lt;br /&gt;                       // size(byte) then the other two&lt;br /&gt;            case 2:&lt;br /&gt;                params.add(new InterpolationBicubic(8));&lt;br /&gt;                break; // Supposed to produce better than above, but also larger&lt;br /&gt;                       // size(byte)&lt;br /&gt;            case 3:&lt;br /&gt;                params.add(new InterpolationBicubic2(8));&lt;br /&gt;                break; // Supposed to produce the best of the two, but also&lt;br /&gt;                       // largest size(byte)&lt;br /&gt;            default:&lt;br /&gt;                params.add(new InterpolationBilinear(8));&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            switch (renderingType) {&lt;br /&gt;            case 1:&lt;br /&gt;                result = JAI.create("scale", params);&lt;br /&gt;                break;&lt;br /&gt;            case 2:&lt;br /&gt;                RenderingHints qualityHints = new RenderingHints(&lt;br /&gt;                        RenderingHints.KEY_RENDERING,&lt;br /&gt;                        RenderingHints.VALUE_RENDER_QUALITY);&lt;br /&gt;                result = JAI.create("SubsampleAverage", params, qualityHints);&lt;br /&gt;                break;&lt;br /&gt;            default:&lt;br /&gt;                result = JAI.create("scale", params);&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setImageToNull() {&lt;br /&gt;        image = null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Crops the image and stores the result&lt;br /&gt;     * &lt;br /&gt;     * @param edgeX&lt;br /&gt;     *            Horizontal crop. The image will be cropped edgeX/2 on both&lt;br /&gt;     *            sides.&lt;br /&gt;     * @param edgeY&lt;br /&gt;     *            Vertical crop. The image will be cropped edgeY/2 on top and&lt;br /&gt;     *            bottom.&lt;br /&gt;     */&lt;br /&gt;    public void crop(float edgeX, float edgeY) {&lt;br /&gt;        ParameterBlock params = new ParameterBlock();&lt;br /&gt;        params.addSource(image);&lt;br /&gt;        params.add((float) (edgeX / 2));// x origin&lt;br /&gt;        params.add((float) (edgeY / 2));// y origin&lt;br /&gt;        params.add((float) (getWidth() - edgeX));// width&lt;br /&gt;        params.add((float) (getHeight() - edgeY));// height&lt;br /&gt;        result = JAI.create("crop", params);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Crops the image to a square, centered, and stores it in the result image&lt;br /&gt;     * &lt;br /&gt;     */&lt;br /&gt;    public void square() {&lt;br /&gt;        float border = getWidth() - getHeight();&lt;br /&gt;        float cropX, cropY;&lt;br /&gt;        if (border &gt; 0) {&lt;br /&gt;            cropX = border;&lt;br /&gt;            cropY = 0;&lt;br /&gt;        } else {&lt;br /&gt;            cropX = 0;&lt;br /&gt;            cropY = -border;&lt;br /&gt;        }&lt;br /&gt;        crop(cropX, cropY);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Applies the currently loaded mask and alpha to the image&lt;br /&gt;     */&lt;br /&gt;    public void applyMask() {&lt;br /&gt;        ParameterBlock params = new ParameterBlock();&lt;br /&gt;        params.addSource(mask);&lt;br /&gt;        params.addSource(image);&lt;br /&gt;        params.add(alpha);&lt;br /&gt;        params.add(null);&lt;br /&gt;        params.add(new Boolean(false));&lt;br /&gt;        result = JAI.create("composite", params, null);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is the example how to use it.&lt;br /&gt;&lt;pre class="brush: java"&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;public class Main {&lt;br /&gt;    public static void main(String[] args) throws IOException {&lt;br /&gt;        ImageTool imageTool = new ImageTool();&lt;br /&gt;        imageTool.load("/home/sverdianto/Pictures/tiger.jpg");&lt;br /&gt;        imageTool.thumbnail(100);&lt;br /&gt;        imageTool.writeResult("/home/sverdianto/Pictures/a.png", "PNG");&lt;br /&gt;&lt;br /&gt;        ImageTool imageTool2 = new ImageTool();&lt;br /&gt;        imageTool2.load("/home/sverdianto/Pictures/tiger.jpg");&lt;br /&gt;        imageTool2.thumbnailSpecial(100, 100, 3, 2); // see the thumbnailSpecial JavaDoc&lt;br /&gt;        imageTool2.writeResult("/home/sverdianto/Pictures/b.png", "PNG");&lt;br /&gt;&lt;br /&gt;        ImageTool imageTool3 = new ImageTool();&lt;br /&gt;        imageTool3.load("/home/sverdianto/Pictures/tiger.jpg");&lt;br /&gt;        imageTool3.thumbnailSpecial(100, 100, 3, 2);&lt;br /&gt;        imageTool3.swapSource();&lt;br /&gt;        imageTool3.square(); // square the thumbnail&lt;br /&gt;        imageTool3.writeResult("/home/sverdianto/Pictures/c.png", "PNG");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-49722951647375671?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/49722951647375671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2011/06/java-thumbnail-generator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/49722951647375671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/49722951647375671'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2011/06/java-thumbnail-generator.html' title='Java Thumbnail Generator'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-NauUDs1XJAM/TgHn1DVliPI/AAAAAAAAADM/_6Z7NeS3MQ4/s72-c/tiger.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-820836116137699792</id><published>2011-06-21T01:25:00.003+07:00</published><updated>2011-06-21T01:29:18.773+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><category scheme='http://www.blogger.com/atom/ns#' term='playframework'/><title type='text'>Sequence generator with PlayFramework, JPA, and PostgreSQL</title><content type='html'>I have been recently making some websites using &lt;a href="http://www.playframwork.org"&gt;PlayFramework&lt;/a&gt; but has just noticed something about auto-generated Id number behavior when using &lt;a href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt; as database.&lt;br /&gt;&lt;br /&gt;I usually create a Model (which is a JPA entity) by extending play.db.jpa.Model which actually have an auto generated Id property and a lot of very useful database related operations. PostgreSQL uses sequence for auto-generated number. By extending the play.db.jpa.Model, you actually use only one sequence generator for all your models. Thats making my first insert to a table (second or so, if you have more than one table) does not always start from 1.&lt;br /&gt;&lt;br /&gt;I then decided to use one sequence per table by doing this following changes:&lt;br /&gt;1. Extends play.db.jpa.GenericModel instead&lt;br /&gt;2. Add an Id property to each model class&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;"&gt;@Entity&lt;br /&gt;public class Token extends GenericModel {&lt;br /&gt;&lt;br /&gt;  @Id&lt;br /&gt;  @SequenceGenerator(name = "Token_generator", sequenceName = "Token_sequence")&lt;br /&gt;  @GeneratedValue(generator = "Token_generator")&lt;br /&gt;  public Long id;&lt;br /&gt;&lt;br /&gt;  ...omitted...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3. Recreate all the table&lt;br /&gt;&lt;br /&gt;This happens only when you are using sequence as number generator (PostgreSQL and Oracle AFAIK?), MySQL should not have this kind of behavior because MySQL use AUTO_INCREMENT instead of sequence generator.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-820836116137699792?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/820836116137699792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2011/06/sequence-generator-with-playframework.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/820836116137699792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/820836116137699792'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2011/06/sequence-generator-with-playframework.html' title='Sequence generator with PlayFramework, JPA, and PostgreSQL'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-8700686237043510260</id><published>2011-06-15T00:19:00.010+07:00</published><updated>2011-07-15T21:47:48.721+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Hashtag Ajax using JQuery</title><content type='html'>Hashtag Ajax being more popular nowdays. Gmail, Twitter, and other modern Ajax websites applying this method in their web. So what is Hashtag Ajax?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;Hashtag Ajax is an Ajax based page navigation without sacrificing SEO, browser bookmarking and back button.&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;So what its look like? and how it works?&lt;br /&gt;&lt;br /&gt;Look at this following example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;http://example.com/index.html&lt;br /&gt;http://example.com/about.html&lt;br /&gt;http://example.com/contact.html&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Instead of having those conventional URL which require browser reload when navigating each other, Hashtag ajax would use this following URL (example):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;http://example.com/#!:/index.html&lt;br /&gt;http://example.com/#!:/about.html&lt;br /&gt;http://example.com/#!:/contact.html&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hash symbol (#) in URL commonly used as an anchor to a section of a webpage. Without javascript all above links just load the same page index.html.&lt;br /&gt;&lt;br /&gt;Thanks to window.location.hash and JQuery ajax (or other who uses XmlHttpRequest) we can use hash to navigate pages. A simple way can do this: getting the hash value, remove the string code (in this example is #!:) and load the resulting path into &lt;b&gt;JQuery.load()&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;I wrote a script that scan all a links with &lt;b&gt;#!:[path]&lt;/b&gt; pattern and bind the click function using JQuery to load target pages into target div.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: javascript;"&gt;// call init&lt;br /&gt;$(init);&lt;br /&gt;&lt;br /&gt;function init() {&lt;br /&gt;  ajax_page_handler();&lt;br /&gt;  page_load($(window.location).attr("hash")); // goto first page if #!: is available&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function page_load($href) {&lt;br /&gt;  if($href != undefined &amp;&amp; $href.substring(0, 3) == '#!:') {&lt;br /&gt;    $('#content').load($href.substring(3)); // replace body the #content with loaded html&lt;br /&gt;    $('html, body').animate({scrollTop:0}, 'slow'); // bonus&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * This method load #content on every url hash change&lt;br /&gt; * &lt;br /&gt; * @return&lt;br /&gt; */&lt;br /&gt;function ajax_page_handler() {&lt;br /&gt;  $(window).bind('hashchange', function () {&lt;br /&gt;    $href = $(window.location).attr("hash");&lt;br /&gt;    page_load($href);&lt;br /&gt;  });&lt;br /&gt;  // this allow you to reload by clicking the same link&lt;br /&gt;  $('a[href^="#!:"]').live('click', function() {&lt;br /&gt;    $curhref = $(window.location).attr("hash");&lt;br /&gt;    $href = $(this).attr('href');&lt;br /&gt;    if($curhref == $href) {&lt;br /&gt;      page_load($href);&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, build your websites, download JQuery, and load JQury and this script inside your pages.&lt;br /&gt;And then change all url to use #!:, dont forget to have main div #content as a place where content loaded and Bang!. You have a simple Ajax website.&lt;br /&gt;&lt;br /&gt;Download the example &lt;a href="http://dl.dropbox.com/u/3579854/hashtag.zip"&gt;here (http://dl.dropbox.com/u/3579854/hashtag.zip)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-8700686237043510260?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/8700686237043510260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2011/06/hashtag-ajax-using-jquery.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/8700686237043510260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/8700686237043510260'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2011/06/hashtag-ajax-using-jquery.html' title='Hashtag Ajax using JQuery'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-8172379684643091071</id><published>2011-06-06T18:22:00.004+07:00</published><updated>2011-06-24T14:05:01.620+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Ubuntu 11.04 Natty Narwhal</title><content type='html'>Setelah sekian lama menggunakan Mac, akhirnya untuk kepentingan pekerjaan saya pun beralih ke Linux (sebenernya sih gara-gara Mac nya rusyak... :P).&lt;br /&gt;&lt;br /&gt;Sempat memilih-milih distro apa yang tepat untuk saya pakai development kegiatan sehari-hari, dengan pilihan Fedora Core 14, Ubuntu 11.04, Linux Mint.&lt;br /&gt;&lt;br /&gt;Setelah coba install semua, kok rasanya Ubuntu 11.04 ini sedikit beda ya... Desktop managernya unik banget - namanya Unity. Secara kenyamanan saya jatuh cinta sama Unity ini yang ternyata adalah subproject dari ubuntu.&lt;br /&gt;&lt;br /&gt;Berikut adalah gambar tampilan Ubuntu 11.04. Kelihatan keren kan? :-)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-jx9Am9-J5Qw/Tey3TIVTvzI/AAAAAAAAAB0/h34vsaqzi18/s1600/desktop.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="225" src="http://2.bp.blogspot.com/-jx9Am9-J5Qw/Tey3TIVTvzI/AAAAAAAAAB0/h34vsaqzi18/s400/desktop.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Itu dari segi tampilan :D gimana dengan fitur-fitur lainnya?&lt;br /&gt;Well, dibanding dengan Fedora Core, aplikasi yang terinstall di Ubuntu lebih stabil. Mulai dari Video Player, Control Panel, Development Tools dan Package Manager boleh diacungkan Jempol. Yang paling saya suka dari Ubuntu ini adalah ketika Modem HSDPA saya sudah otomatis terdeteksi dan jalan hanya dengan konfigurasi melalui kontrol panel GUI yang sangat minimal - No More Command Line dan Driver Compile :)).&lt;br /&gt;&lt;br /&gt;Coba deh... saya menunggu versi 11.10-nya nih... semoga banyak improvement Ubuntu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-8172379684643091071?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/8172379684643091071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2011/06/ubuntu-1104-maverick-meerkat.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/8172379684643091071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/8172379684643091071'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2011/06/ubuntu-1104-maverick-meerkat.html' title='Ubuntu 11.04 Natty Narwhal'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-jx9Am9-J5Qw/Tey3TIVTvzI/AAAAAAAAAB0/h34vsaqzi18/s72-c/desktop.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-4505334299464984960</id><published>2010-11-22T11:35:00.000+07:00</published><updated>2010-11-22T11:35:52.309+07:00</updated><title type='text'>Reposting old blog entries...</title><content type='html'>Baru ngerepost postingan lama dari sverdianto.net, banyak yang ilang :(&lt;br /&gt;Tapi gpp deh menuh2in blog :P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-4505334299464984960?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/4505334299464984960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2010/11/reposting-old-blog-entries.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/4505334299464984960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/4505334299464984960'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2010/11/reposting-old-blog-entries.html' title='Reposting old blog entries...'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-8267460932006629260</id><published>2010-11-22T11:33:00.000+07:00</published><updated>2010-11-22T11:33:01.843+07:00</updated><title type='text'>Mewarnai OS X Terminal.app :)</title><content type='html'>Udah cari-cari dari lama gimana caranya bikin Terminal di OS X berwarna kayak di Linux, akhirnya nemu juga &lt;br /&gt;&lt;br /&gt;Caranya gamphang :) :&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Pastikan terminal typenya xterm-color, bisa di cek di Terminal -&gt; Preferences&lt;/li&gt;&lt;li&gt;Edit atau buat file ~/bash_profile.&lt;/li&gt;export CLICOLOR=1export LSCOLORS=ExFxCxDxBxegedabagacad&lt;/li&gt;&lt;li&gt;Exit terminal dan…&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Ini gambarnya:&lt;br /&gt;&lt;b&gt;[[IMAGE LOST]]&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Selamat mencoba…&lt;br /&gt;&lt;br /&gt;update:&lt;br /&gt;Ternyata warnanyapun bisa di customize ini detailnya:&lt;br /&gt;&lt;br /&gt;Variabel LSCOLORS itu ternyata menyatakan warna yang ditampilkan oleh program ls.&lt;br /&gt;Warna yang bisa digunakan:&lt;br /&gt;&lt;br /&gt;a - black&lt;br /&gt;b - red&lt;br /&gt;c - green&lt;br /&gt;d - brown&lt;br /&gt;e - blue&lt;br /&gt;f - magenta&lt;br /&gt;g - cyan&lt;br /&gt;h - light grey&lt;br /&gt;x - default foreground or background&lt;br /&gt;Jika ingin dicetak tebal, lambang warna tersebut bisa dituliskan dengan huruf besar (uppercase).&lt;br /&gt;&lt;br /&gt;Warna-warna tersebut dituliskan berdasarkan susunan attribute (setiap attribute terdiri dari foreground diikuti dengan background):&lt;br /&gt;&lt;br /&gt;directory&lt;br /&gt;symbolic link&lt;br /&gt;socket&lt;br /&gt;pipe&lt;br /&gt;executable&lt;br /&gt;block special&lt;br /&gt;character special&lt;br /&gt;executable with setuid bit set&lt;br /&gt;executable with setgid bit set&lt;br /&gt;directory writable to others, with sticky bit&lt;br /&gt;directory writable to others, without sticky bit&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ref:&lt;br /&gt;- MacTips&lt;br /&gt;- http://www.wikihow.com/Change-Colors-and-Set-Paths-&amp;-Aliases-in-Your-Startup-File&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-8267460932006629260?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/8267460932006629260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2010/11/mewarnai-os-x-terminalapp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/8267460932006629260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/8267460932006629260'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2010/11/mewarnai-os-x-terminalapp.html' title='Mewarnai OS X Terminal.app :)'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-398266928688834524</id><published>2010-01-08T17:15:00.000+07:00</published><updated>2010-01-08T17:15:08.963+07:00</updated><title type='text'>How to prevent non root to execute a perl script</title><content type='html'>Here is a short script to do that. This help me much...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# check if root&lt;br /&gt;$user = `whoami`;&lt;br /&gt;chomp $user;&lt;br /&gt;if($user ne "root") {&lt;br /&gt; print "You must be root to execute this command. Please login as root or use sudo command!\n";&lt;br /&gt; exit;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-398266928688834524?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/398266928688834524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2010/01/how-to-prevent-non-root-to-execute-perl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/398266928688834524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/398266928688834524'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2010/01/how-to-prevent-non-root-to-execute-perl.html' title='How to prevent non root to execute a perl script'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-5611753053148542991</id><published>2009-12-04T23:14:00.002+07:00</published><updated>2011-06-21T01:30:08.712+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='checkstyle'/><title type='text'>Checkstyle: Custom Inner Class Checker</title><content type='html'>&lt;div&gt;A week ago, I have successfully installed the &lt;a href="https://hudson.dev.java.net/"&gt;Hudson&lt;/a&gt; &lt;a href="http://wiki.hudson-ci.org/display/HUDSON/Violations+Plugin"&gt;Violation&lt;/a&gt; plugin to report our projects &lt;a href="http://checkstyle.sourceforge.net/"&gt;Checkstyle&lt;/a&gt; result on our Hudson installation.&amp;nbsp;As the first step to force developers not to write a&amp;nbsp;&lt;span style="font-style: italic;"&gt;System.out.print/println &lt;/span&gt;but instead using Log4J, I only enable module that only reject class having&amp;nbsp;&lt;i&gt;System.out.print/println&lt;/i&gt;. Interestingly we caught some developers that have write &lt;i&gt;System.out.print/println&lt;/i&gt; function in many classes of our projects :)).&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;A few days ago, my Boss assigned a new task to also reject any class that have Inner Class. I really agree to this, inner class makes class looks ugly and it would hard to find without a great help of advanced IDE.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I looked at the website and search Google to find if Checkstyle already have Inner Class checker module - but I couldn't find it anywhere. So, I decided to write a simple checker for this. As reference - the Checkstyle "&lt;a href="http://checkstyle.sourceforge.net/extending.html"&gt;Extending Plugin&lt;/a&gt;" page provide everything I need.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Firstly, I need to write the checker implementation class, here it is:&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: java;"&gt;package com.jawasoft.checkstyle.checks;&lt;br /&gt;&lt;br /&gt;import java.io.File;&lt;br /&gt;&lt;br /&gt;import com.puppycrawl.tools.checkstyle.api.Check;&lt;br /&gt;import com.puppycrawl.tools.checkstyle.api.DetailAST;&lt;br /&gt;import com.puppycrawl.tools.checkstyle.api.SeverityLevel;&lt;br /&gt;import com.puppycrawl.tools.checkstyle.api.TokenTypes;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * @author sverdianto&lt;br /&gt; *&lt;br /&gt; */&lt;br /&gt;public class InnerClassCheck extends Check {&lt;br /&gt;&lt;br /&gt; public InnerClassCheck() {&lt;br /&gt;  // default severity is error&lt;br /&gt;  setSeverity(SeverityLevel.ERROR.getName());&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public int[] getDefaultTokens() {&lt;br /&gt;  return new int[]{TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF};&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void visitToken(DetailAST aAST) {&lt;br /&gt;  String fileName = this.getFileContents().getFilename();&lt;br /&gt;  File file = new File(fileName);&lt;br /&gt;  String javaName = file.getName().substring(0, file.getName().lastIndexOf(".java")); // remove extension&lt;br /&gt;&lt;br /&gt;  if(aAST.branchContains(TokenTypes.IDENT)) {&lt;br /&gt;   DetailAST id = aAST.findFirstToken(TokenTypes.IDENT);&lt;br /&gt;   if(!javaName.equals(id.getText())) {&lt;br /&gt;    log(aAST, "Inner class is not allowed!");&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;The idea is to compare the actual class name with the file name without .java extension which must be a valid public class name. If it doesn't match it would be treated as an inner class even though it is declared in root and as public.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Compile the class (dont forget to also include checkstyle &amp;amp; its dependencies jars to the classpath).&lt;br /&gt;And add new module to the checkstyle configuration file:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;module name="Checker"&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;module name="TreeWalker"&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;module name="com.jawasoft.checkstyle.checks.InnerClassCheck"&gt;&lt;br /&gt;    &lt;/module&gt;&lt;br /&gt;&lt;/module&gt;&lt;br /&gt;&lt;/module&gt;&lt;/pre&gt;&lt;br /&gt;Now, try running checkstyle using new configuration, you shoul see some error if you have inner class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-5611753053148542991?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/5611753053148542991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/12/checkstyle-custom-inner-class-checker.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/5611753053148542991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/5611753053148542991'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/12/checkstyle-custom-inner-class-checker.html' title='Checkstyle: Custom Inner Class Checker'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-4075637947576815978</id><published>2009-11-18T22:03:00.004+07:00</published><updated>2010-04-29T01:14:58.544+07:00</updated><title type='text'>My New Casio Watch</title><content type='html'>Hehe... I finally bought &lt;a href="http://www.casio-intl.com/wat/edifice/edifice_chrono/ef-537.html"&gt;Casio Edifice 537&lt;/a&gt; (so happy). Actually, this is my first watch I bought with my own money (and select it myself). It is quite simple, the case &amp;amp; the bend are made of stainless steel, black background, and 30 minutes chronograph (sadly no date indicator).&lt;br /&gt;&lt;br /&gt;Here are the pictures:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_iARlOEW-q3A/SwQLztZH9UI/AAAAAAAAAAU/AelNauEmho0/s1600/IMG_6982.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_iARlOEW-q3A/SwQLztZH9UI/AAAAAAAAAAU/AelNauEmho0/s200/IMG_6982.JPG" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_iARlOEW-q3A/SwQLwScRbUI/AAAAAAAAAAM/2-41Q9GJeMk/s1600/IMG_6986.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_iARlOEW-q3A/SwQLwScRbUI/AAAAAAAAAAM/2-41Q9GJeMk/s200/IMG_6986.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-4075637947576815978?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/4075637947576815978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/11/my-new-casio-watch.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/4075637947576815978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/4075637947576815978'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/11/my-new-casio-watch.html' title='My New Casio Watch'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_iARlOEW-q3A/SwQLztZH9UI/AAAAAAAAAAU/AelNauEmho0/s72-c/IMG_6982.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-1567768648352569063</id><published>2009-09-27T22:51:00.004+07:00</published><updated>2009-09-27T23:17:43.541+07:00</updated><title type='text'>Adding Enum support to CakePHP</title><content type='html'>CakePHP have been previously support Enum, but it was removed because Enum is actually MySQL specific datatype.&lt;br /&gt;&lt;br /&gt;I really need this feature and so I decided to hack the form helper to support Enum type.&lt;br /&gt;It is basically adding new Enum handler to the input() method of form helper which is used by scaffolding or user custom form.&lt;br /&gt;&lt;br /&gt;Here is the patch of [CAKE_ROOT]/cake/libs/view/helpers/form.php file:&lt;br /&gt;&lt;pre class="brush: php;"&gt;582c582&lt;br /&gt;&lt; &lt;br /&gt;---&lt;br /&gt;&gt;   &lt;br /&gt;613a614,625&lt;br /&gt;&gt;     &lt;br /&gt;&gt;  // enum special handling&lt;br /&gt;&gt;  preg_match('/enum\((.*)\)/i', $type, $matches);&lt;br /&gt;&gt;  if(!empty($matches[1])) {&lt;br /&gt;&gt;    $options['type'] = 'select';&lt;br /&gt;&gt;    $enum_options = explode(',', $matches[1]);&lt;br /&gt;&gt;    $options['options'] = array();&lt;br /&gt;&gt;    foreach($enum_options as $_option) {&lt;br /&gt;&gt;      $option = trim($_option, "\"' ");&lt;br /&gt;&gt;      $options['options'][$option] = $option;&lt;br /&gt;&gt;    }&lt;br /&gt;&gt;  }&lt;br /&gt;624c636&lt;br /&gt;&lt; &lt;br /&gt;---&lt;br /&gt;&gt;    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once you patched the file, every Enum fields will be displayed as a HTML select instead of a normal text field. Goodluck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-1567768648352569063?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/1567768648352569063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/09/adding-enum-support-to-cakephp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/1567768648352569063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/1567768648352569063'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/09/adding-enum-support-to-cakephp.html' title='Adding Enum support to CakePHP'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-9202867637942704313</id><published>2009-09-03T19:27:00.005+07:00</published><updated>2010-01-23T14:36:11.519+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Admin'/><category scheme='http://www.blogger.com/atom/ns#' term='Email'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet'/><title type='text'>Setting up DomainKeys (DK) and DomainKeys Identified Mail (DKIM) for Sendmail</title><content type='html'>A short introduction abort &lt;a href="http://en.wikipedia.org/wiki/DomainKeys"&gt;DK&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/DomainKeys_Identified_Mail"&gt;DKIM&lt;/a&gt;. DK and DKIM is basically an email authentication system to verify the DNS of email sender and message integrity.&lt;br /&gt;&lt;br /&gt;How it works? Let say a user (john@example.org) send an email to other people using Yahoo! account (jen@yahoo.com). The MTA of example.org will sign the message using private key before delivering the email. Once the message received by target server (in this case Yahoo!), they will verify the message using example.org public key published as TXT info by the example.org name server.&lt;br /&gt;&lt;br /&gt;DK or DKIM will guarantee that a verified email is coming from the right person or organization.&lt;br /&gt;&lt;br /&gt;I will explain how to install DK and DKIM with Sendmail. Why DK and DKIM? some email server might support only DK and some might support advanced DK which is DKIM.&lt;br /&gt;&lt;br /&gt;Requirements:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sendmail 8.13 or higher (with Milter support)&lt;/li&gt;&lt;li&gt;OpenSSL&lt;/li&gt;&lt;li&gt;Bind DNS server (or any other DNS server)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Installation:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install this following packages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;latest OpenSSL + OpenSSL-devel package from YUM&lt;/li&gt;&lt;li&gt;Sendmail, Sendmail-cf and Sendmail-devel for Milter support&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Download DK-Milter and DKIM-Milter packages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://downloads.sourceforge.net/project/dk-milter/DomainKeys%20Milter/1.0.2/dk-milter-1.0.2.tar.gz?use_mirror=jaist"&gt;http://downloads.sourceforge.net/project/dk-milter/DomainKeys%20Milter/1.0.2/dk-milter-1.0.2.tar.gz?use_mirror=jaist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://downloads.sourceforge.net/project/dkim-milter/DKIM%20Milter/2.8.3/dkim-milter-2.8.3.tar.gz?use_mirror=jaist"&gt;http://downloads.sourceforge.net/project/dkim-milter/DKIM%20Milter/2.8.3/dkim-milter-2.8.3.tar.gz?use_mirror=jaist&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Build and compilation&lt;br /&gt;DK-Milter &amp; DKIM-Milter have quite similar installation step configuration.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;DKIM-Milter&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Extract package&lt;/li&gt;&lt;li&gt;Copy configuration file from site.config.m4.dist to devtools/Site/site.config.m4 (use default configuration for now)&lt;/li&gt;&lt;li&gt;Build &amp; install:&lt;br /&gt;&lt;pre&gt;&lt;b&gt;# sh Build&lt;br /&gt;# sh Build install&lt;br /&gt;&lt;/b&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;DK-Milter&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Extract package&lt;/li&gt;&lt;li&gt;Copy configuration file from site.config.m4.dist to devtools/Site/site.config.m4 (use default configuration for now)&lt;/li&gt;&lt;li&gt;Build &amp; install:&lt;br /&gt;&lt;pre&gt;&lt;b&gt;# sh Build&lt;br /&gt;# sh Build install&lt;/b&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Key generation and DNS setup&lt;br /&gt;Both DK &amp; DKIM require secure key pair to sign the mail. DKIM comes with tools called &lt;b&gt;dkim-genkey&lt;/b&gt;, run it and 2 files will be created, one is the private key and the other one is the DNS TXT entry.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Copy &amp; rename the default.private to /var/db/dk-dkim/mail&lt;/li&gt;&lt;li&gt;Update bind and add this follwoing TXT entry:&lt;br /&gt;&lt;pre&gt;&lt;b&gt;mail._domainkey.example.org. IN TXT "v=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMa7vGwI3zb+y8DL5cI5YU0PrdWhrpOTDLrdwnkGzmj0SEYj4lk7Vsq2f40uiB9qL70OB4HTT+eTeFgL1TNPPcMUkQRj8zKX98BwF+CCQ7wpIbJfoMKGpMQaKbzHcfjWjqWbYGpk4WtM4oj/aSklrIr71w0GpjhONDj+M/QT5w/wIDAQAB"&lt;br /&gt;_domainkey.example.org.  IN TXT "o=~"&lt;br /&gt;&lt;/b&gt;&lt;/pre&gt;Where p=?, ? is the public key generated by dkim-genkey.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Restart the DNS service.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Sendmail integration&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Configure sendmail milter&lt;br /&gt;We will run DK on port 8891 and DKIM on port 8892&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Edit /etc/mail/sendmail.mc and add this following lines&lt;br /&gt;&lt;pre&gt;&lt;b&gt;INPUT_MAIL_FILTER(`dk-filter', `S=inet:8891@localhost')&lt;/b&gt;&lt;br /&gt;&lt;b&gt;INPUT_MAIL_FILTER(`dkim-filter', `S=inet:8892@localhost')&lt;/b&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Rebuild sendmail config by running&lt;br /&gt;&lt;pre&gt;&lt;b&gt;# make sendmail.cf&lt;br /&gt;# make restart&lt;/b&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Start DK and DKIM&lt;br /&gt;&lt;pre&gt;&lt;b&gt;# /usr/sbin/useradd -r domainkeys&lt;br /&gt;# chown -Rf domainkeys /var/db/dk-dkim/&lt;br /&gt;# /usr/bin/dk-filter -l -p inet:8891@localhost -c simple -b s -h -d example.org -D -s /var/db/dk-dkim/mail -S mail -u domainkeys -m MSA&lt;br /&gt;# /usr/sbin/dkim-filter -l -p inet:8892@localhost -c simple -b s -h -d example.org -D -k /var/db/dk-dkim/mail -s mail -S rsa-sha256 -u domainkeys -m MSA&lt;br /&gt;&lt;/b&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;To test send an email to DK or DKIM aware mail provider (eg: Yahoo!). You should see something like this in mail the header:  Signature: &lt;pre&gt;&lt;b&gt;X-DKIM: Sendmail DKIM Filter v2.8.3 host3.example.org n82G7Xwh008144&lt;br /&gt;DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=example.org;&lt;br /&gt; s=mail; t=1251907653; i=@example.org;&lt;br /&gt; bh=XgF6uYzcgcROQtd83d1Evx8x2uW+SniFx69skZp5azo=;&lt;br /&gt; h=Date:From:Message-Id:To:Subject;&lt;br /&gt; b=d2J8AiWmqecDvFvOva6bahU0TEB+q5RYonPCMh/24UpKBzAIczV7ohhW73LcVJaKw&lt;br /&gt;  xshr0SFRDaOE48iGp6FxC1yfHEFr7nix6vzvhc2Hr5MgwsRy1HwwI36mkPrhrnbMb/&lt;br /&gt;  d2Khy498P9z7qj+yNF99RRxq7NAftRbFFxbVb10s=&lt;br /&gt;X-DomainKeys: Sendmail DomainKeys Filter v1.0.2 host3.example.org n82G7Xwh008144&lt;br /&gt;DomainKey-Signature: a=rsa-sha1; s=mail; d=example.org; c=simple; q=dns;&lt;br /&gt; b=ndEg7XD5PnWe1/SHdKygFZ9s8ZwwhmFBRVjNwEaPytptgEl5XJ41DWwjspq5+4huj&lt;br /&gt; 6SFBQMmVnEOvRwMPTvL8o9mD+M41vaV0X7dLSNYnC9K3JjFpZiwzLonGNag2TwrQBc3&lt;br /&gt; zzxZqpol5SSOsi93sZ7j3FMNTPdjVIhcsHdvHVw=&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;/pre&gt;Verification: &lt;pre&gt;&lt;b&gt;Authentication-Results: mta117.mail.re3.yahoo.com  from=mail.example.org; domainkeys=pass (ok); from=example.org; dkim=pass (ok)&lt;/b&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Thats all&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-9202867637942704313?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/9202867637942704313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/09/setting-up-domainkeys-dk-and-domainkeys.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/9202867637942704313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/9202867637942704313'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/09/setting-up-domainkeys-dk-and-domainkeys.html' title='Setting up DomainKeys (DK) and DomainKeys Identified Mail (DKIM) for Sendmail'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-2603751460826363168</id><published>2009-08-21T13:54:00.019+07:00</published><updated>2009-08-22T20:05:50.211+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='How To'/><category scheme='http://www.blogger.com/atom/ns#' term='Blog'/><title type='text'>How to setup SyntaxHighlighter on Blogger</title><content type='html'>Just installed SyntaxHighlighter v2.x to my Blogger.&lt;br /&gt;&lt;br /&gt;I've searched the internet to SyntaxHighlighter-izing my Blogger site and found lots of interesting way to setup (widget, manual install, etc).&lt;br /&gt;But, most of them are still using version published on GoogleCode (http://code.google.com/p/syntaxhighlighter/) which is v1.5.1.&lt;br /&gt;&lt;br /&gt;The author, &lt;a href="http://alexgorbatchev.com/"&gt;Alex Gorbatchev&lt;/a&gt;, He is actually publishing SyntaxHighlighter on his own website. Surprisingly, it even have newer version than the one on GoogleCode, and provide &lt;a href="http://alexgorbatchev.com/pub/sh/"&gt;public hosted scripts&lt;/a&gt; :D.&lt;br /&gt;&lt;br /&gt;So, how to install:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Firstly, you don't need to download/upload any files, just use Alex public scripts &lt;a href="http://alexgorbatchev.com/pub/sh/"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt; It have lots of version on it, I prefer to use latest version of SyntaxHighlighter (you may choose another).&lt;/li&gt;&lt;li&gt; Go to Blogger theme configuration, and edit your HTML file and insert following lines just befor &amp;lt;/head&amp;gt; tag :&lt;/li&gt;&lt;pre class="brush: html;"&gt;&lt;link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/&gt;&lt;br /&gt;&lt;link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/&gt;&lt;br /&gt;&lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/&gt;&lt;br /&gt;&lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/&gt;&lt;br /&gt;&lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/&gt;&lt;br /&gt;&lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/&gt;&lt;br /&gt;&lt;script type='text/javascript'&gt;&lt;br /&gt;	SyntaxHighlighter.config.clipboardSwf = 'scripts/clipboard.swf';&lt;br /&gt;	SyntaxHighlighter.config.bloggerMode = true;&lt;br /&gt;	SyntaxHighlighter.all();&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;/pre&gt;&lt;li&gt;To add another brush, insert new &amp;lt;script&amp;gt; tag referencing to any available brush inside scripts folder.&lt;br /&gt;&lt;li&gt;And, taraa!!! you see the example above ;). For more information about how to use visit: &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter:Usage"&gt;http://alexgorbatchev.com/wiki/SyntaxHighlighter:Usage&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;This is cool!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-2603751460826363168?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/2603751460826363168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/08/syntaxhighlighter-test.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/2603751460826363168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/2603751460826363168'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/08/syntaxhighlighter-test.html' title='How to setup SyntaxHighlighter on Blogger'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-158745979846439612</id><published>2009-08-21T10:59:00.003+07:00</published><updated>2009-08-21T11:44:26.548+07:00</updated><title type='text'>Pindah ke Blogger.com</title><content type='html'>Setelah tidak melanjutkan hosting blog sendiri di &lt;a href="http://www.sverdianto.net"&gt;www.sverdianto.net&lt;/a&gt;, saya memutuskan untuk memindah aktifitas menulis blog di situs Blogger ini.&lt;div&gt;Sayangnya tulisan lama lupa di backup jadi hilang semua deh :(&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-158745979846439612?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/158745979846439612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/08/pindah-ke-bloggercom.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/158745979846439612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/158745979846439612'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2009/08/pindah-ke-bloggercom.html' title='Pindah ke Blogger.com'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-3899398148982948474</id><published>2007-08-01T11:27:00.001+07:00</published><updated>2011-06-21T01:30:57.076+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='swing'/><title type='text'>RegEat - My First Swing App</title><content type='html'>Finally, I made my first Swing application.&lt;br /&gt;Named RegEat, a simple Regular Expression Tools.&lt;br /&gt;I write this application because at the first time I tried to find a simpe regex tools, it was so hard, but I found some - Reggy and RegExpress.&lt;br /&gt;&lt;br /&gt;This application built by Java application, Swing based, and using standard JDK RegEx engine (java.util.regex) and developed using NetBeans IDE.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/regeat"&gt;Download RegEat&lt;/a&gt;&lt;br /&gt;A Zip file that contains NetBeans project and Binary JAR. To run simply double click dist/RegEat.jar&lt;br /&gt;&lt;br /&gt;Still, this application is far from good. But I’d appreciate any comments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-3899398148982948474?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/3899398148982948474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2007/08/regeat-my-first-swing-app.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/3899398148982948474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/3899398148982948474'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2007/08/regeat-my-first-swing-app.html' title='RegEat - My First Swing App'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-2042674025954908526</id><published>2007-08-01T11:26:00.000+07:00</published><updated>2010-11-22T11:27:12.334+07:00</updated><title type='text'>Gotong Royong di Kantor</title><content type='html'>Huaahh….. abis gotong-gotong meja di kantor  abis rubah posisi nih tim Java + Web Designer…Si Bos minta kita di atur per-team… sebab team Community bakalan kesibukan. Ada project rame…&lt;br /&gt;&lt;br /&gt;Kembali ke laptop (kata Tukul)…&lt;br /&gt;&lt;br /&gt;Ini skrinsut layout kantor yang baru di obrak abrek biar sedikit lebih luas…&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[[IMAGE LOST]]&lt;/b&gt; hiks...&lt;br /&gt;&lt;br /&gt;Tapi posisi meja saya engga berubah… tetep aja kedinginan di bawah ase (Air Conditioner).&lt;br /&gt;Mejanya jadi kecilan… tapi sokeh lah… masih pas buat kompie sayah &lt;br /&gt;&lt;br /&gt;Di meja tengah yang gede (yang kayak meja makan), di tempati team Community, yang duduk di sana Benny Whelan, Jeffry Pianov, Degger juga ada Bill.&lt;br /&gt;&lt;br /&gt;Pinggiran dikit, ada team GovDex (yang ngerjain B2B) - ada Aviandri (baju biru), Kristina (.NET) sama Sayah sendiri (cuman lagi moto, jadi gak keliatan) &lt;br /&gt;&lt;br /&gt;Si bos (Ronsen) pindah ke pojokan deketan ama si Danny (cuman potonya dari belakan)… &lt;br /&gt;&lt;br /&gt;Gimana kah suasana baru ini??????&lt;br /&gt;&lt;br /&gt;**some text removed by admin**&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-2042674025954908526?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/2042674025954908526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2007/08/gotong-royong-di-kantor.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/2042674025954908526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/2042674025954908526'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2007/08/gotong-royong-di-kantor.html' title='Gotong Royong di Kantor'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-2069180195285662011</id><published>2007-08-01T11:24:00.000+07:00</published><updated>2010-11-22T11:26:06.163+07:00</updated><title type='text'>Ujian bikin STRESS…</title><content type='html'>Gile… sejak senin kemarin di kampus lagi ujian…&lt;br /&gt;Bener bener deh… dibuat pusing nih kepala… terutama matakuliah MetKuan (Metode Kuantitatif)… phew…&lt;br /&gt;&lt;br /&gt;Udah kuliah jarang masuk… ^_^v - UTS gak ikut… Tugas gak ngumpulin pula… lengkap sudah penderitaan… hua….&lt;br /&gt;&lt;br /&gt;Hari ini ujian TBO (Teori Bahasa Otomata), besok Bahasa Pemrograman, yang terakhir Kalkulus (Pelajaran paling gak suka)… udah gitu bayaran semester belum lagi…&lt;br /&gt;&lt;br /&gt;—&lt;br /&gt;&lt;br /&gt;Di sisi lain, lagi beresin proyek kantor belum kelar… baru alpha release dari beberapa bulan lalu start. koding… koding… koding…&lt;br /&gt;&lt;br /&gt;Oh iya lupa…  satu lagi program abang Jambi, dia nelpon mo ambil kemaren… tapi lupa euy… komputer rumah keformat bulan kemaren gara-gara nyoba-nyoba OSX86 di kompie rumah  hua…hua… (nangis… bukan ketawa)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-2069180195285662011?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/2069180195285662011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2007/08/ujian-bikin-stress.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/2069180195285662011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/2069180195285662011'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2007/08/ujian-bikin-stress.html' title='Ujian bikin STRESS…'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2225800074603699030.post-8532437674035808216</id><published>2007-08-01T11:20:00.002+07:00</published><updated>2010-11-22T11:22:29.684+07:00</updated><title type='text'>OS X Leopard</title><content type='html'>Wow… I saw WWDC keynote last Wednesday with my friends.&lt;br /&gt;&lt;br /&gt;Apple will launch their new innovative Operating System OS X 10 codename Leopard in October 2007.&lt;br /&gt;The price is only $129 (converted: about Rp. 1.100.000).&lt;br /&gt;&lt;br /&gt;My friend, Aviandri asked to the Apple distributor on Point Square Lebak Bulus about upgrading Tiger to Leopard.&lt;br /&gt;They said we could just upgrade current Tiger to Leopard with no cost if we bougt the Mac hardware from their store. (Wooo… I bought my MacBook Pro there :p - but I need the CD’s)&lt;br /&gt;&lt;br /&gt;Aaahh… October… 4 months…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2225800074603699030-8532437674035808216?l=sverdianto-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sverdianto-blog.blogspot.com/feeds/8532437674035808216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sverdianto-blog.blogspot.com/2007/08/os-x-leopard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/8532437674035808216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2225800074603699030/posts/default/8532437674035808216'/><link rel='alternate' type='text/html' href='http://sverdianto-blog.blogspot.com/2007/08/os-x-leopard.html' title='OS X Leopard'/><author><name>Sukma Verdianto</name><uri>http://www.blogger.com/profile/02733309523664622974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-3VoHBjXqIyE/TezpfV3lItI/AAAAAAAAACA/4CRe4dFrUGU/s220/sephia.jpg'/></author><thr:total>0</thr:total></entry></feed>
