Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Tuesday, 16 February 2016

Install Eclipse-Che on Ubuntu server

  • Install jdk1.8+ & set JAVA_HOME

  • Install Docker

  • $ which curl
    $ sudo apt-get update
    $ sudo apt-get install curl
    $ curl -sSL https://get.docker.com/ | sh
    
    If you would like to use Docker as a non-root user, you should now consider
    adding your user to the "docker" group with something like:
    $ sudo usermod -aG docker serveradmin
    
    Remember that you will have to log out and back in for this to take effect!
  • Verify docker is installed correctly

  • $ docker run hello-world
    or
    $ sudo docker run hello-world
    
    This command downloads a test image and runs it in a container.
  • Download eclipse-che installation jar

  • The reason why I download the installation jar (JAR Universal Extractor) instead of directly use docker image with following command is that way isn't work for me. It's always showing some error.
    $ docker run -it -p 1104:8080 codenvy/che
    
  • Install eclipse-che

  • $ sudo mkdir /usr/local/eclipse-che-4.0.0-RC3
    $ sudo chown -R serveradmin:serveradmin /usr/local/eclipse-che-4.0.0-RC3
    $ java -jar eclipse-che-latest.jar 
    

    You should select "/usr/local/eclipse-che-4.0.0-RC3" as target installation dir.
  • Add execute permisson to TOMCAT script

  • $ cd /usr/local/eclipse-che-4.0.0-RC3/tomcat/bin
    $ chmod +x *.sh
    
  • Set CHE_HOME

  • $ vi ~/.bashrc
    
    Add the line to it
    export CHE_HOME=/usr/local/eclipse-che-4.0.0-RC3
    
    Reload
    $ source ~/.bashrc
    
    Create link to /usr/bin
    $ sudo ln -s /usr/local/eclipse-che-4.0.0-RC3/bin/che.sh /usr/bin/che
    
    Now,you can start Eclipse-Che by
    $ che start
    








    Friday, 12 February 2016

    • Get current running class dir path
    • String jarOrBuildClassDir = getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
      

      It will return 'build/classes/main' if you run it on IDE

      /Users/demo/workspace/MyDemo/build/classes/main/
      

      It will return the location of 'jar' file which the class archived if you run it in a jar file

      /Users/demo/workspace/MyDemo/install/MyDemo/lib/MyDemo.jar
      
    • Get special resources file path that copy from 'src/main/java/resources/com/demo/test.xsl'
    • URL xslFileURL = getClass().getResource("/com/demo/test.xsl")
      

      It will return 'build/resources/main' if you run it on IDE

      /Users/demo/workspace/MyDemo/build/resources/main/com/demo/test.xsl
      

      It will return the location of 'jar' file which the class archived if you run it in a jar file

      file:/Users/demo/workspace/MyDemo/install/MyDemo/lib/MyDemo.jar!/com/demo/test.xsl
      

    Thursday, 8 May 2014

    Java client read content from URL with SSL

    • Java client
    • import javax.net.ssl.HostnameVerifier;
      import javax.net.ssl.HttpsURLConnection;
      import javax.net.ssl.SSLSession;
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.net.URISyntaxException;
      import java.net.URL;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.nio.file.Paths;
      
      public class PDFTester {
          private static final int FILE_BUFFER_SIZE = 2048;
          public static final String CONTENT_TYPE_PDF = "application/pdf";
          public static byte[] readPDFFromURL(URL url) throws IOException {
              System.setProperty("javax.net.ssl.trustStore", "C:/temp/myCA.jks");
              System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
      
              HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
              httpsURLConnection.setHostnameVerifier(new HostnameVerifier() {
                  public boolean verify(String hostname, SSLSession session) {
                      return true;
                  }
              });
              httpsURLConnection.connect();
      
              byte[] buffer = new byte[FILE_BUFFER_SIZE];
              int lengthOfByteToBeWrite;
              try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                   InputStream inputStream = httpsURLConnection.getInputStream()) {
                  while ((lengthOfByteToBeWrite = inputStream.read(buffer)) != -1) {
                      byteArrayOutputStream.write(buffer, 0, lengthOfByteToBeWrite);
                  }
                  byteArrayOutputStream.flush();
                  return byteArrayOutputStream.toByteArray();
              } catch (IOException e) {
                  throw e;
              }
          }
      
          public static void main(String[] args) throws IOException, URISyntaxException {
              URL url = new URL("https://www.sample.com/pdf");
              byte[] bytes = readPDFFromURL(url);
              Path path = Paths.get("c:/temp/test.pdf");
              Files.write(path, bytes);
          }
      }
      
    • SSL base knowledge:
      Implementing SSL / TLS using Java

    Thursday, 11 April 2013

    Practice of customize JAXB Schema-2-JAVA use xjc

    JAXB Marshalling with Custom Namespace Prefixes
    • You have an XML schema with multiple XML namespaces.
    • You generate a JAXB model with xjc.
    • You build a JAXB document model and use the JAXB Marshaller to create XML from the model.
    • You want to override the default namespace prefixes ns1, ns2, ... created by the Marshaller.
    XJC bind Schema-2-java
    • You want use customization java package
    • You want use more meanful java property name to replace xml element/attribute, default use element/attribute name
    • You want to override the default XmlAdapter Adapter1.java, Adapter2.java... created by xjc.

    Target xsd file
    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:ns1="http://seanshou.blogspot.com/XMLSchema" 
    targetNamespace="http://seanshou.blogspot.com/XMLSchema" 
    elementFormDefault="qualified" 
    attributeFormDefault="unqualified">
     <xs:element name="comment" type="xs:string"/>
     <xs:element name="employee" type="ns1:EmployeeType">
      <xs:annotation>
       <xs:documentation>Comment describing your root element</xs:documentation>
      </xs:annotation>
     </xs:element>
     <xs:complexType name="USAddress">
      <xs:sequence>
       <xs:element name="name" type="xs:string"/>
       <xs:element name="street" type="xs:string"/>
       <xs:element name="city" type="xs:string"/>
       <xs:element name="state" type="xs:string"/>
       <xs:element name="zip" type="xs:string"/>
      </xs:sequence>
      <xs:attribute name="country" type="xs:NMTOKEN" use="required" fixed="US"/>
     </xs:complexType>
     <xs:complexType name="EmployeeType">
      <xs:sequence>
       <xs:element name="address" type="ns1:USAddress"/>
       <xs:element name="paySlip" type="ns1:payment"/>
       <xs:element ref="ns1:comment"/>
      </xs:sequence>
      <xs:attribute name="userId" type="xs:int" use="required"/>
     </xs:complexType>
     <xs:complexType name="payment">
      <xs:sequence>
       <xs:element name="baseSalary" type="xs:int"/>
       <xs:element name="supernation" type="xs:integer" nillable="true" minOccurs="0"/>
       <xs:element name="bonus" type="xs:integer" nillable="true" minOccurs="0"/>
      </xs:sequence>
     </xs:complexType>
    </xs:schema>
    
    • line[5]: The generated classes by xjc will qualified by namespace: http://seanshou.blogspot.com/XMLSchema
    • line[33,34]: The customization to use use-defined adapter BigIntegerXmlAdapter for xs:integer
    Customized external bindings file
    <?xml version="1.0" encoding="UTF-8"?>
    <jxb:bindings
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
            xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
            xmlns:namespace="http://jaxb2-commons.dev.java.net/namespace-prefix"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd
            http://jaxb2-commons.dev.java.net/namespace-prefix http://java.net/projects/jaxb2-commons/sources/svn/content/namespace-prefix/trunk/src/main/resources/prefix-namespace-schema.xsd"
            jxb:extensionBindingPrefixes="xjc"
            version="2.1">
        <jxb:bindings schemaLocation="Employee-Definiation.xsd" node="/xs:schema">
            <jxb:globalBindings fixedAttributeAsConstantProperty="false" collectionType="java.util.ArrayList"
                                typesafeEnumBase="xs:NCName" choiceContentProperty="false"
                                typesafeEnumMemberName="generateError"
                                enableFailFastCheck="false" generateIsSetMethod="false" underscoreBinding="asCharInWord">
                <xjc:javaType name="java.math.BigInteger" xmlType="xs:integer"
                              adapter="com.blogspot.seanshou.jaxb.adapter.BigIntegerXmlAdapter"/>
            </jxb:globalBindings>
            <jxb:schemaBindings>
                <jxb:package name="com.blogspot.seanshou.jaxb.xml"/>
            </jxb:schemaBindings>
            <jxb:bindings>
                <namespace:prefix name="NS1"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:element[@name='employee']">
                <jxb:class name="EmployeePojo"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:complexType[@name='EmployeeType']">
                <jxb:bindings node=".//xs:element[@name='address']">
                  <jxb:property name="mailAddress"/>
                </jxb:bindings>
            </jxb:bindings>
        </jxb:bindings>
    </jxb:bindings>
    
    • line[17,18]: customize to special java type use pre-defined 'XmlAdater'
    • line[21]: customize to java package name
    • Note that this customization is per namespace. That is, even if your schema is split into multiple schema documents, you cannot put them into different packages if they are all in the same namespace
    • line[24]: customize namespace prefix when XJC convert Schema-2-Java, the prefix 'NS1' will be append package-info.java
    • use JAXB Namespace-prefix plugin
    • line[26,28]: binding root xml elemment employee to java class EmployeeType
    • line[30,32]: binding child xml elemment address of employee to java property mailAddress of class EmployeeType

    pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.blogspot.seanshou.jaxb</groupId>
        <artifactId>JAXB-Schema-to-Java-showcase</artifactId>
        <version>1.0</version>
        <build>
            <plugins>
                <plugin>
                    <!-- jaxb plugin -->
                    <groupId>org.jvnet.jaxb2.maven2</groupId>
                    <artifactId>maven-jaxb2-plugin</artifactId>
                    <version>0.8.3</version>
                    <configuration>
                        <!--
                        <generatePackage>com.blogspot.seanshou.jaxb.xml</generatePackage>
                        <catalog>src/main/resources/catalog.xml</catalog>
                        -->
                        <schemaDirectory>src/main/resources</schemaDirectory>
                        <schemaIncludes>
                            <include>*.xsd</include>
                        </schemaIncludes>
                        <bindingDirectory>src/main/resources</bindingDirectory>
                        <bindingIncludes>
                            <include>bindings.xml</include>
                        </bindingIncludes>
                        <args>
                            <arg>-extension</arg>
                            <arg>-Xnamespace-prefix</arg>
                        </args>
                        <removeOldOutput>true</removeOldOutput>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>generate</goal>
                            </goals>
                        </execution>
                    </executions>
                        <dependencies>
                            <dependency>
                                <groupId>org.jvnet.jaxb2_commons</groupId>
                                <artifactId>jaxb2-namespace-prefix</artifactId>
                                <version>1.1</version>
                            </dependency>
                        </dependencies>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                        <encoding>${project.build.sourceEncoding}</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        <dependencies>
            <dependency>
                <groupId>javax.xml.bind</groupId>
                <artifactId>jaxb-api</artifactId>
                <version>2.2.6</version>
            </dependency>
            <dependency>
                <groupId>javax.xml</groupId>
                <artifactId>jaxb-impl</artifactId>
                <version>2.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.1</version>
            </dependency>
        </dependencies>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    </project>
    
    
    Pre-defined BigIntegerXmlApater.java
    package com.blogspot.seanshou.jaxb.adapter;
    
    import javax.xml.bind.DatatypeConverter;
    import javax.xml.bind.annotation.adapters.XmlAdapter;
    import java.math.BigInteger;
    
    import static org.apache.commons.lang3.StringUtils.EMPTY;
    import static org.apache.commons.lang3.StringUtils.isBlank;
    
    
    public class BigIntegerXmlAdapter extends XmlAdapter<String, BigInteger> {
        @Override
        public BigInteger unmarshal(String value) throws Exception {
            if (isBlank(value)) {
                return BigInteger.ZERO;
            }
            return DatatypeConverter.parseInteger(value);
        }
    
        @Override
        public String marshal(BigInteger value) throws Exception {
            if (value == null) {
                return EMPTY;
            }
            return DatatypeConverter.printInteger(value);
        }
    }
    
    

    Generated classes by xjc
    • EmployeePojo.java
    • package com.blogspot.seanshou.jaxb.xml;
      
      import javax.xml.bind.JAXBElement;
      import javax.xml.namespace.QName;
      
      public class EmployeePojo extends JAXBElement<EmployeeType>
      {
      
          protected final static QName NAME = new QName("http://seanshou.blogspot.com/XMLSchema", "employee");
      
          public EmployeePojo(EmployeeType value) {
              super(NAME, ((Class) EmployeeType.class), null, value);
          }
      
          public EmployeePojo() {
              super(NAME, ((Class) EmployeeType.class), null, null);
          }
      
      }
      
      • line[6]: Customized by line[26-28] in bindings.xml
    • EmployeeType.java
    • package com.blogspot.seanshou.jaxb.xml;
      
      import javax.xml.bind.annotation.XmlAccessType;
      import javax.xml.bind.annotation.XmlAccessorType;
      import javax.xml.bind.annotation.XmlAttribute;
      import javax.xml.bind.annotation.XmlElement;
      import javax.xml.bind.annotation.XmlType;
      
      
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "EmployeeType", propOrder = {
          "mailAddress",
          "paySlip",
          "comment"
      })
      public class EmployeeType {
      
          @XmlElement(name = "address", required = true)
          protected USAddress mailAddress;
          @XmlElement(required = true)
          protected Payment paySlip;
          @XmlElement(required = true)
          protected String comment;
          @XmlAttribute(name = "userId", required = true)
          protected int userId;
      
          public USAddress getMailAddress() {
              return mailAddress;
          }
      
          public void setMailAddress(USAddress value) {
              this.mailAddress = value;
          }
      
          public Payment getPaySlip() {
              return paySlip;
          }
      
          public void setPaySlip(Payment value) {
              this.paySlip = value;
          }
      
          public String getComment() {
              return comment;
          }
      
      
          public void setComment(String value) {
              this.comment = value;
          }
      
      
          public int getUserId() {
              return userId;
          }
      
          public void setUserId(int value) {
              this.userId = value;
          }
      
      }
      
      • line[18,19]: Customized by line[30-32] in bindings.xml
    • Payment.java
    • package com.blogspot.seanshou.jaxb.xml;
      
      import java.math.BigInteger;
      import javax.xml.bind.JAXBElement;
      import javax.xml.bind.annotation.XmlAccessType;
      import javax.xml.bind.annotation.XmlAccessorType;
      import javax.xml.bind.annotation.XmlElementRef;
      import javax.xml.bind.annotation.XmlType;
      
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "payment", propOrder = {
          "baseSalary",
          "supernation",
          "bonus"
      })
      public class Payment {
      
          protected int baseSalary;
          @XmlElementRef(name = "supernation", namespace = "http://seanshou.blogspot.com/XMLSchema", type = JAXBElement.class)
          protected JAXBElement<BigInteger> supernation;
          @XmlElementRef(name = "bonus", namespace = "http://seanshou.blogspot.com/XMLSchema", type = JAXBElement.class)
          protected JAXBElement<BigInteger> bonus;
      
          public int getBaseSalary() {
              return baseSalary;
          }
      
          public void setBaseSalary(int value) {
              this.baseSalary = value;
          }
      
          public JAXBElement<BigInteger> getSupernation() {
              return supernation;
          }
      
          public void setSupernation(JAXBElement<BigInteger> value) {
              this.supernation = value;
          }
      
          public JAXBElement<BigInteger> getBonus() {
              return bonus;
          }
      
          public void setBonus(JAXBElement<BigInteger> value) {
              this.bonus = value;
          }
      
      }
      
    • USAddress.java
    • package com.blogspot.seanshou.jaxb.xml;
      
      import javax.xml.bind.annotation.XmlAccessType;
      import javax.xml.bind.annotation.XmlAccessorType;
      import javax.xml.bind.annotation.XmlAttribute;
      import javax.xml.bind.annotation.XmlElement;
      import javax.xml.bind.annotation.XmlSchemaType;
      import javax.xml.bind.annotation.XmlType;
      import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
      import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
      
      
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "USAddress", propOrder = {
          "name",
          "street",
          "city",
          "state",
          "zip"
      })
      public class USAddress {
      
          @XmlElement(required = true)
          protected String name;
          @XmlElement(required = true)
          protected String street;
          @XmlElement(required = true)
          protected String city;
          @XmlElement(required = true)
          protected String state;
          @XmlElement(required = true)
          protected String zip;
          @XmlAttribute(name = "country", required = true)
          @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
          @XmlSchemaType(name = "NMTOKEN")
          protected String country;
      
          public String getName() {
              return name;
          }
      
          public void setName(String value) {
              this.name = value;
          }
      
          public String getStreet() {
              return street;
          }
      
          public void setStreet(String value) {
              this.street = value;
          }
      
          public String getCity() {
              return city;
          }
      
          public void setCity(String value) {
              this.city = value;
          }
      
          public String getState() {
              return state;
          }
      
          public void setState(String value) {
              this.state = value;
          }
      
          public String getZip() {
              return zip;
          }
      
          public void setZip(String value) {
              this.zip = value;
          }
      
          public String getCountry() {
              if (country == null) {
                  return "US";
              } else {
                  return country;
              }
          }
      
          public void setCountry(String value) {
              this.country = value;
          }
      }
      
    • ObjectFactory.java
    • package com.blogspot.seanshou.jaxb.xml;
      
      import java.math.BigInteger;
      import javax.xml.bind.JAXBElement;
      import javax.xml.bind.annotation.XmlElementDecl;
      import javax.xml.bind.annotation.XmlRegistry;
      import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
      import javax.xml.namespace.QName;
      import com.blogspot.seanshou.jaxb.adapter.BigIntegerXmlAdapter;
      
      @XmlRegistry
      public class ObjectFactory {
      
          private final static QName _Comment_QNAME = new QName("http://seanshou.blogspot.com/XMLSchema", "comment");
          private final static QName _PaymentSupernation_QNAME = new QName("http://seanshou.blogspot.com/XMLSchema", "supernation");
          private final static QName _PaymentBonus_QNAME = new QName("http://seanshou.blogspot.com/XMLSchema", "bonus");
      
          public ObjectFactory() {
          }
      
          public EmployeeType createEmployeeType() {
              return new EmployeeType();
          }
      
          public Payment createPayment() {
              return new Payment();
          }
      
          public USAddress createUSAddress() {
              return new USAddress();
          }
      
          @XmlElementDecl(namespace = "http://seanshou.blogspot.com/XMLSchema", name = "comment")
          public JAXBElement<String> createComment(String value) {
              return new JAXBElement<String>(_Comment_QNAME, String.class, null, value);
          }
      
          @XmlElementDecl(namespace = "http://seanshou.blogspot.com/XMLSchema", name = "employee")
          public EmployeePojo createEmployeePojo(EmployeeType value) {
              return new EmployeePojo(value);
          }
      
          @XmlElementDecl(namespace = "http://seanshou.blogspot.com/XMLSchema", name = "supernation", scope = Payment.class)
          @XmlJavaTypeAdapter(BigIntegerXmlAdapter.class)
          public JAXBElement<BigInteger> createPaymentSupernation(BigInteger value) {
              return new JAXBElement<BigInteger>(_PaymentSupernation_QNAME, BigInteger.class, Payment.class, value);
          }
      
          @XmlElementDecl(namespace = "http://seanshou.blogspot.com/XMLSchema", name = "bonus", scope = Payment.class)
          @XmlJavaTypeAdapter(BigIntegerXmlAdapter.class)
          public JAXBElement<BigInteger> createPaymentBonus(BigInteger value) {
              return new JAXBElement<BigInteger>(_PaymentBonus_QNAME, BigInteger.class, Payment.class, value);
          }
      }
      
      • line[44,50]: Customized by line[17-18] in bindings.xml
    • package-info.java
    • @javax.xml.bind.annotation.XmlSchema(namespace = "http://seanshou.blogspot.com/XMLSchema", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = {
          @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://seanshou.blogspot.com/XMLSchema", prefix = "NS1")
      })
      package com.blogspot.seanshou.jaxb.xml;
      
      • line[2]: Customized by line[24] in bindings.xml
    Reference

    Thursday, 14 March 2013

    How to make JAXB marshal/unmarshal show errors

    JAXB by default silently ignores errors. Try adding this code to throw an exception if something goes wrong.
    unmarshaller.setEventHandler(
        new ValidationEventHandler() {
            public boolean handleEvent(ValidationEvent event ) {
                ValidationEventLocator locator = event.getLocator();
                String errorMessage = "Line:Column[" + locator.getLineNumber() + ":" + locator.getColumnNumber() + "]:" + event.getMessage();
                throw new RuntimeException(errorMessage, event.getLinkedException());
            }
    });
    

    Wednesday, 3 October 2012

    Java Swing PDF Viewer

    I'll use pdf-renderer to create an pdf viewer in java swing application.
    • Dependencies
    • 
          org.swinglabs
          pdf-renderer
          1.0.5
      
      
          com.google.guava
          guava
          13.0.1
      
      
    • PDF Viewer
    • import com.google.common.base.CharMatcher;
      import com.sun.pdfview.PDFFile;
      import com.sun.pdfview.PDFPage;
      import com.sun.pdfview.PagePanel;
      
      import javax.swing.*;
      import java.awt.*;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.io.File;
      import java.io.IOException;
      import java.io.RandomAccessFile;
      import java.nio.ByteBuffer;
      import java.nio.channels.FileChannel;
      
      import static com.google.common.base.Strings.isNullOrEmpty;
      
      public class PdfViewer extends JPanel {
          private static enum Navigation {GO_FIRST_PAGE, FORWARD, BACKWARD, GO_LAST_PAGE, GO_N_PAGE}
      
          private static final CharMatcher POSITIVE_DIGITAL = CharMatcher.anyOf("0123456789");
          private static final String GO_PAGE_TEMPLATE = "%s of %s";
          private static final int FIRST_PAGE = 1;
          private int currentPage = FIRST_PAGE;
          private JButton btnFirstPage;
          private JButton btnPreviousPage;
          private JTextField txtGoPage;
          private JButton btnNextPage;
          private JButton btnLastPage;
          private PagePanel pagePanel;
          private PDFFile pdfFile;
      
          public PdfViewer() {
              initial();
          }
      
          private void initial() {
              setLayout(new BorderLayout(0, 0));
              JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
              add(topPanel, BorderLayout.NORTH);
              btnFirstPage = createButton("|<<");
              topPanel.add(btnFirstPage);
              btnPreviousPage = createButton("<<");
              topPanel.add(btnPreviousPage);
              txtGoPage = new JTextField(10);
              txtGoPage.setHorizontalAlignment(JTextField.CENTER);
              topPanel.add(txtGoPage);
              btnNextPage = createButton(">>");
              topPanel.add(btnNextPage);
              btnLastPage = createButton(">>|");
              topPanel.add(btnLastPage);
              JScrollPane scrollPane = new JScrollPane();
              add(scrollPane, BorderLayout.CENTER);
              JPanel viewPanel = new JPanel(new BorderLayout(0, 0));
              scrollPane.setViewportView(viewPanel);
      
              pagePanel = new PagePanel();
              Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
              pagePanel.setPreferredSize(screenSize);
              viewPanel.add(pagePanel, BorderLayout.CENTER);
      
              disableAllNavigationButton();
      
              btnFirstPage.addActionListener(new PageNavigationListener(Navigation.GO_FIRST_PAGE));
              btnPreviousPage.addActionListener(new PageNavigationListener(Navigation.BACKWARD));
              btnNextPage.addActionListener(new PageNavigationListener(Navigation.FORWARD));
              btnLastPage.addActionListener(new PageNavigationListener(Navigation.GO_LAST_PAGE));
              txtGoPage.addActionListener(new PageNavigationListener(Navigation.GO_N_PAGE));
          }
      
          private JButton createButton(String text) {
              JButton button = new JButton(text);
              button.setPreferredSize(new Dimension(55, 20));
      
              return button;
          }
      
          private void disableAllNavigationButton() {
              btnFirstPage.setEnabled(false);
              btnPreviousPage.setEnabled(false);
              btnNextPage.setEnabled(false);
              btnLastPage.setEnabled(false);
          }
      
          private boolean isMoreThanOnePage(PDFFile pdfFile) {
              return pdfFile.getNumPages() > 1;
          }
      
          private class PageNavigationListener implements ActionListener {
              private final Navigation navigation;
      
              private PageNavigationListener(Navigation navigation) {
                  this.navigation = navigation;
              }
      
              public void actionPerformed(ActionEvent e) {
                  if (pdfFile == null) {
                      return;
                  }
      
                  int numPages = pdfFile.getNumPages();
                  if (numPages <= 1) {
                      disableAllNavigationButton();
                  } else {
                      if (navigation == Navigation.FORWARD && hasNextPage(numPages)) {
                          goPage(currentPage, numPages);
                      }
      
                      if (navigation == Navigation.GO_LAST_PAGE) {
                          goPage(numPages, numPages);
                      }
      
                      if (navigation == Navigation.BACKWARD && hasPreviousPage()) {
                          goPage(currentPage, numPages);
                      }
      
                      if (navigation == Navigation.GO_FIRST_PAGE) {
                          goPage(FIRST_PAGE, numPages);
                      }
      
                      if (navigation == Navigation.GO_N_PAGE) {
                          String text = txtGoPage.getText();
                          boolean isValid = false;
                          if (!isNullOrEmpty(text)) {
                              boolean isNumber = POSITIVE_DIGITAL.matchesAllOf(text);
                              if (isNumber) {
                                  int pageNumber = Integer.valueOf(text);
                                  if (pageNumber >= 1 && pageNumber <= numPages) {
                                      goPage(Integer.valueOf(text), numPages);
                                      isValid = true;
                                  }
                              }
                          }
      
                          if (!isValid) {
                              JOptionPane.showMessageDialog(PdfViewer.this, format("Invalid page number '%s' in this document", text));
                              txtGoPage.setText(format(GO_PAGE_TEMPLATE, currentPage, numPages));
                          }
                      }
                  }
              }
      
              private void goPage(int pageNumber, int numPages) {
                  currentPage = pageNumber;
                  PDFPage page = pdfFile.getPage(currentPage);
                  pagePanel.showPage(page);
                  boolean notFirstPage = isNotFirstPage();
                  btnFirstPage.setEnabled(notFirstPage);
                  btnPreviousPage.setEnabled(notFirstPage);
                  txtGoPage.setText(format(GO_PAGE_TEMPLATE, currentPage, numPages));
                  boolean notLastPage = isNotLastPage(numPages);
                  btnNextPage.setEnabled(notLastPage);
                  btnLastPage.setEnabled(notLastPage);
              }
      
              private boolean hasNextPage(int numPages) {
                  return (++currentPage) <= numPages;
              }
      
              private boolean hasPreviousPage() {
                  return (--currentPage) >= FIRST_PAGE;
              }
      
              private boolean isNotLastPage(int numPages) {
                  return currentPage != numPages;
              }
      
              private boolean isNotFirstPage() {
                  return currentPage != FIRST_PAGE;
              }
          }
      
          public PagePanel getPagePanel() {
              return pagePanel;
          }
      
          public void setPDFFile(PDFFile pdfFile) {
              this.pdfFile = pdfFile;
              currentPage = FIRST_PAGE;
              disableAllNavigationButton();
              txtGoPage.setText(format(GO_PAGE_TEMPLATE, FIRST_PAGE, pdfFile.getNumPages()));
              boolean moreThanOnePage = isMoreThanOnePage(pdfFile);
              btnNextPage.setEnabled(moreThanOnePage);
              btnLastPage.setEnabled(moreThanOnePage);
          }
      }
      
      Line:58-59 automatically match the current screen resolution. The default is 800*600.

      The utility method "format" is here: format

    • Tester
    • public static void main(String[] args) {
              try {
                  long heapSize = Runtime.getRuntime().totalMemory();
                  System.out.println("Heap Size = " + heapSize);
      
                  JFrame frame = new JFrame("PDF Test");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
                  //load a pdf from a byte buffer
                  File file = new File("/Users/Sean/Documents/test-pdf.pdf");
                  RandomAccessFile raf = new RandomAccessFile(file, "r");
                  FileChannel channel = raf.getChannel();
                  ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
                  final PDFFile pdffile = new PDFFile(buf);
                  PdfViewer pdfViewer = new PdfViewer();
                  pdfViewer.setPDFFile(pdffile);
                  frame.add(pdfViewer);
                  frame.pack();
                  frame.setVisible(true);
      
                  PDFPage page = pdffile.getPage(0);
                  pdfViewer.getPagePanel().showPage(page);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
    • screen shots


    Wednesday, 19 September 2012

    How to create or initialize Generic Type Array


  • solution 1





  • Limitation: It's not work if input array is null.

    public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive) {
            if (array == null) {
                return null;
            }
    
            if (startIndexInclusive < 0) {
                startIndexInclusive = 0;
            }
            if (endIndexExclusive > array.length) {
                endIndexExclusive = array.length;
            }
    
            Class<?> type = array.getClass().getComponentType();
            int newSize = endIndexExclusive - startIndexInclusive;
            if (newSize < 0) {
                final T[] emptyArray = (T[]) Array.newInstance(type, 0);
                return emptyArray;
            }
    
            T[] subarray = (T[]) Array.newInstance(type, newSize);
            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
            return subarray;
        }
    
  • solution 2
  • It's work if input array is null. But it's more verbose for invoking.
    public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive, Class<T>> clazz) {
         T[] emptyArray = (T[]) Array.newInstance(clazz, 0);
    
            if (array == null) {
                return emptyArray;
            }
    
            if (startIndexInclusive < 0) {
                startIndexInclusive = 0;
            }
            if (endIndexExclusive > array.length) {
                endIndexExclusive = array.length;
            }
    
            if (newSize < 0) {
                return emptyArray;
            }
    
            T[] subarray = (T[]) Array.newInstance(clazz, newSize);
            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
            return subarray;
        }
    

    Tuesday, 18 September 2012

    Java Swing JTextField: Number only and give length



  • Solution 1

  • Simple but It can't work for "CTRL + V" scenario
    private class NumberOnlyAdapter extends KeyAdapter {
    
            private final int maxLength;
    
            private NumberOnlyAdapter(int maxLength) {
                this.maxLength = maxLength;
            }
    
            @Override
            public void keyTyped(KeyEvent e) {
                char typed = e.getKeyChar();
                CharMatcher notDigit = noneOf("0123456789").and(isNot((char) VK_BACK_SPACE)).and(isNot((char) VK_DELETE));
                JTextField textField = (JTextField) e.getComponent();
                if (notDigit.apply(typed) || textField.getText().length() >= maxLength) {
                    e.consume();
                }
            }
    
        }
    
    ...
    int maxLength = 8;
    JTextField textField = new JTextField();
    textField.addKeyListener(new NumberOnlyAdapter(maxLength));
    
  • Solution 2

  • It's work for all conditions
    import static org.apache.commons.lang3.StringUtils.*;
    
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DocumentFilter;
    
    public class NumericOnlyAndMaxLengthFilter extends DocumentFilter {
        private int maxLength = 0;
    
    
        public NumericOnlyAndMaxLengthFilter() {
           // allow any length of numeric
        }
    
        public NumericOnlyAndMaxLengthFilter(int maxLength) {
            this.maxLength = maxLength;
        }
    
        @Override
        public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
            if (isNumeric(string)) {
                if (isExceedMaxLength(fb, string)) {
                    return;
                }
                super.insertString(fb, offset, string, attr);
            }
        }
    
        @Override
        public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
            if (isNumeric(text)) {
                if (isExceedMaxLength(fb, text)) {
                    return;
                }
                super.insertString(fb, offset, text, attrs);
            }
        }
    
        private boolean isExceedMaxLength(FilterBypass fb, String text) {
            return maxLength > 0 && (fb.getDocument().getLength() + text.length()) > maxLength;
        }
    }
    
    ...
    int maxLength = 8;
    JTextField textField = new JTextField();
    ((AbstractDocument)textField .getDocument()).setDocumentFilter(new NumericOnlyAndMaxLengthFilter(maxLength));
    

    Thursday, 13 September 2012

    Maven generate HTML Junit report

    • add to pom.xml
    • 
          org.apache.maven.plugins
          maven-surefire-plugin
          
              true
          
      
      
      
          org.jvnet.maven-antrun-extended-plugin
          maven-antrun-extended-plugin
          
              
                  test-reports
                  test
                  
                      
                          
                              
                                  
                              
                              
                          
                      
                  
                  
                      run
                  
              
          
          
              
                  org.apache.ant
                  ant-junit
                  1.8.4
              
              
                  org.apache.ant
                  ant-trax
                  1.8.0
              
          
      
      
    • Don't bind the AntRun plugin to the test phase, move the configuration outside the execution and call mvn antrun:run on the command line to generate the reports when wanted.
    • Or use the testFailureIgnore option of the test mojo and set it to true in the surefire plugin
    • Use maven command arguments
    • $mvn test -Dmaven.test.failure.ignore=true
      

    Wednesday, 5 September 2012

    Java - better performance String formatter

    /**
         * Substitutes each {@code %s} in {@code template} with an argument. These
         * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
         * If there are more arguments than placeholders, the unmatched arguments will
         * be appended to the end of the formatted message in square braces.
         *
         * @param template a non-null string containing 0 or more {@code %s}
         *     placeholders.
         * @param args the arguments to be substituted into the message
         *     template. Arguments are converted to strings using
         *     {@link String#valueOf(Object)}. Arguments can be null.
         */
        public static String format(String template, Object... args) {
            template = String.valueOf(template); // null -> "null"
            // start substituting the arguments into the '%s' placeholders
            StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
            int templateStart = 0;
            int i = 0;
            while (i < args.length) {
                int placeholderStart = template.indexOf("%s", templateStart);
                if (placeholderStart == -1) {
                    break;
                }
                builder.append(template.substring(templateStart, placeholderStart));
                builder.append(args[i++]);
                templateStart = placeholderStart + 2;
            }
            builder.append(template.substring(templateStart));
    
            // if we run out of placeholders, append the extra args in square braces
            if (i < args.length) {
                builder.append(" [");
                builder.append(args[i++]);
                while (i < args.length) {
                    builder.append(", ");
                    builder.append(args[i++]);
                }
                builder.append(']');
            }
    
            return builder.toString();
        }
    
       public static void main(String[] args) {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.start();
            String result = Formatter.format("My name is: %s. I was start from: %s. ", "Sean", "25/05/2012", "another value here");
            stopwatch.stop();
            System.out.println(stopwatch.elapsedTime(TimeUnit.NANOSECONDS));
            System.out.println(result);
            stopwatch.reset();
            stopwatch.start();
            result = String.format("My name is: %s. I was start from: %s.", "Sean", "25/05/2012", "another value here");
            stopwatch.stop();
            System.out.println(stopwatch.elapsedTime(TimeUnit.NANOSECONDS));
            System.out.println(result);
        }
    

    Tuesday, 14 August 2012

    Read line (or get line count) from JTextArea with wrap enabled

    public class Demo {
         JTextArea textArea = new JTextArea(text, 5, 50);
         textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
         textArea.setEditable(false);
         textArea.setLineWrap(true);
         textArea.setWrapStyleWord(true);
    
         private static String[] readLinesFromTextArea(JTextArea textArea, int limitRows) {
               String content = textArea.getText();
               String[] lines = new String[limitRows];
               Arrays.fill(lines, "");
               try {
                  int count = 0;
                  int offs = 0;
                  while (offs < content.length() && count < limitRows ) {
                     int end = Utilities.getRowEnd(textArea, offs);
                     String line = StringUtils.substring(content, offs, end);
                     lines[count++] = line;
                     offs = end + 1;
                  }
               } catch (BadLocationException e) {
                 log.error("Read line from 'Other' text area failed. Cause:\n", Throwables.getStackTraceAsString(e));
            }
    
            return lines;
        }
    }
    

    Monday, 6 August 2012

    Use Apache PDFBox convert PDF to image (support BMP,bmp,jpeg,wbmp,gif,png,JPG,jpg,JPEG,WBMP)

    • dependency
    • 
         org.apache.pdfbox
         pdfbox
         1.7.0
      
      
         org.bouncycastle
         bcprov-jdk15
         1.46
      
      
         org.bouncycastle
         bcmail-jdk15
         1.46
      
      
         org.apache.pdfbox
         fontbox
         1.7.0
                         
      
    • Code
    • import au.gov.nsw.police.nodi.common.CustomProperties;
      import org.apache.pdfbox.exceptions.CryptographyException;
      import org.apache.pdfbox.exceptions.InvalidPasswordException;
      import org.apache.pdfbox.pdmodel.PDDocument;
      import org.apache.pdfbox.pdmodel.PDPage;
      import org.apache.pdfbox.util.PDFImageWriter;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      
      import javax.imageio.*;
      import javax.imageio.metadata.IIOInvalidTreeException;
      import javax.imageio.metadata.IIOMetadata;
      import javax.imageio.metadata.IIOMetadataNode;
      import java.awt.*;
      import java.awt.image.BufferedImage;
      import java.awt.image.RenderedImage;
      import java.io.ByteArrayInputStream;
      import java.io.IOException;
      import java.util.Iterator;
      import java.util.List;
      
      import static com.google.common.base.Throwables.getStackTraceAsString;
      
      public class PDFToImage {
          private static final Logger log = LoggerFactory.getLogger(PDFToImage.class);
          private static final String STANDARD_METADATA_FORMAT = "javax_imageio_1.0";
          private static final String PDF_ENCRYPTED_PASSWORD = CustomProperties.getInstance().getProperty("pdf.from.esb.encrypted.password");
          private static final String IMAGE_FORMAT = "png";
          private static final int DEFAULT_IMAGE_RESOLUTION = 256;
      
          public static RenderedImage convertPdfOfGivenPageNumberToRenderImage(PDDocument document, int pageNumber) throws IOException {
              try {
                  decryptDocument(PDF_ENCRYPTED_PASSWORD, document);
      
                  int imageType = BufferedImage.TYPE_INT_RGB;
                  int resolution = DEFAULT_IMAGE_RESOLUTION;
                  try {
                      int screenResolution = Toolkit.getDefaultToolkit().getScreenResolution();
                      if (screenResolution > resolution) {
                          resolution = screenResolution;
                      }
                  } catch (HeadlessException e) {
                      log.debug("As it can't get the screen resolution. Use default resolution: {}", resolution);
                  }
      
                  List pages = document.getDocumentCatalog().getAllPages();
                  PDPage page = (PDPage) pages.get(pageNumber);
                  BufferedImage image = page.convertToImage(imageType, resolution);
                  return covertBufferedImageToRenderImage(image, IMAGE_FORMAT, resolution);
              } finally {
                  if (document != null) {
                      document.close();
                  }
              }
          }
      
          private static void decryptDocument(String password, PDDocument document) throws IOException {
              if (document.isEncrypted()) {
                  try {
                      document.decrypt(password);
                  } catch (InvalidPasswordException e) {
                      log.error("Error: The document is encrypted. Please provide correct PDF_ENCRYPTED_PASSWORD. Cause:\n{}", getStackTraceAsString(e));
                  } catch (CryptographyException e) {
                      log.error(getStackTraceAsString(e));
                  }
              }
          }
      
          private static RenderedImage covertBufferedImageToRenderImage(BufferedImage image, String imageFormat, int resolution) throws IOException {
              ImageWriter imageWriter = null;
              Iterator imageWriterIterator = ImageIO.getImageWritersByFormatName(imageFormat);
              if (imageWriterIterator.hasNext()) {
                  try {
                      imageWriter = imageWriterIterator.next();
                      ImageWriteParam writerParams = imageWriter.getDefaultWriteParam();
                      if (writerParams.canWriteCompressed()) {
                          writerParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                          // reset the compression type if overwritten by setCompressionMode
                          if (writerParams.getCompressionType() == null) {
                              writerParams.setCompressionType(writerParams.getCompressionTypes()[0]);
                          }
                          writerParams.setCompressionQuality(1.0f);
                      }
                      IIOMetadata meta = createMetadata(image, imageWriter, writerParams, resolution);
                      IIOImage iioImage = new IIOImage(image, null, meta);
                      return iioImage.getRenderedImage();
                  } finally {
                      if (imageWriter != null) {
                          imageWriter.dispose();
                      }
                  }
              }
      
              return null;
          }
      
          private static PDDocument loadPdfDocumentFromBytes(byte[] imageOfPdf) throws IOException {
              ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(imageOfPdf);
              return PDDocument.load(byteArrayInputStream);
      
          }
      
          private static PDDocument loadPdfDocumentFromFile(String fileName) throws IOException {
              return PDDocument.load(fileName);
          }
      
          //----------------------Copy from (start): org.apache.pdfbox.util.ImageIOUtil-----------------------------------
          private static IIOMetadata createMetadata(RenderedImage image, ImageWriter imageWriter, ImageWriteParam writerParams, int resolution) {
              ImageTypeSpecifier type;
              if (writerParams.getDestinationType() != null) {
                  type = writerParams.getDestinationType();
              } else {
                  type = ImageTypeSpecifier.createFromRenderedImage(image);
              }
              IIOMetadata meta = imageWriter.getDefaultImageMetadata(type, writerParams);
              return (addResolution(meta, resolution) ? meta : null);
          }
      
          private static boolean addResolution(IIOMetadata meta, int resolution) {
              if (!meta.isReadOnly() && meta.isStandardMetadataFormatSupported()) {
                  IIOMetadataNode root = (IIOMetadataNode) meta.getAsTree(STANDARD_METADATA_FORMAT);
                  IIOMetadataNode dimension = getChildNode(root, "Dimension");
                  IIOMetadataNode horizontalPixelSize = getChildNode(dimension, "HorizontalPixelSize");
                  String pixelSize = Double.toString(resolution / 25.4);
                  horizontalPixelSize.setAttribute("value", pixelSize);
      
                  IIOMetadataNode verticalPixelSize = getChildNode(dimension, "VerticalPixelSize");
                  verticalPixelSize.setAttribute("value", pixelSize);
                  try {
                      meta.mergeTree(STANDARD_METADATA_FORMAT, root);
                  } catch (IIOInvalidTreeException e) {
                      throw new RuntimeException("Cannot update image metadata: " + e.getMessage());
                  }
                  return true;
              }
              return false;
          }
      
      
          private static IIOMetadataNode getChildNode(IIOMetadataNode parentNode, String childNodeName) {
              NodeList nodes = parentNode.getChildNodes();
              for (int i = 0; i < nodes.getLength(); i++) {
                  Node child = nodes.item(i);
                  if (childNodeName.equals(child.getNodeName())) {
                      return (IIOMetadataNode) child;
                  }
              }
      
              return createChildNodeIfNotExist(parentNode, childNodeName);
          }
      
      
          private static IIOMetadataNode createChildNodeIfNotExist(IIOMetadataNode parentNode, String childNodeName) {
              IIOMetadataNode childNode = new IIOMetadataNode(childNodeName);
              parentNode.appendChild(childNode);
              return childNode;
          }
          //----------------------Copy from (end): org.apache.pdfbox.util.ImageIOUtil-----------------------------------
      
          public static void main(String[] args) throws IOException {
              String pdfFile = "c:/temp/test_avo.pdf";
              String outputPrefix = "c:/temp/";
      
              PDDocument document = loadPdfDocumentFromFile(pdfFile);
              int numberOfPages = document.getNumberOfPages();
              for (int i = 0; i < numberOfPages; i++) {
                  int pageNumber = i + 1;
                  RenderedImage renderedImage = convertPdfOfGivenPageNumberToRenderImage(document, pageNumber);
                  // render image to ui or
              }
      
              // if you just want to covert pdf file to image file, it's much easier.
              PDFImageWriter imageWriter = new PDFImageWriter();
              boolean success = imageWriter.writeImage(document, IMAGE_FORMAT, password, startPage, endPage, outputPrefix, BufferedImage.TYPE_INT_RGB, resolution);
              if (!success) {
                  System.err.println("Error: no writer found for image format '" + IMAGE_FORMAT + "'");
                  System.exit(1);
              }
          }
      
    • You can use following code to detected which image format is support
    • public static String getImageFormats() {
              StringBuffer retval = new StringBuffer();
              String[] formats = ImageIO.getReaderFormatNames();
              for (int i = 0; i < formats.length; i++) {
                  retval.append(formats[i]);
                  if (i + 1 < formats.length) {
                      retval.append(",");
                  }
              }
              return retval.toString();
          }
      
    • Dependencies can be download here
    • Others
    • Tiff image need native libary. You can find more information on java.net

    Monday, 30 July 2012

    Soap Web Service with attachment Over JMS

    • dependency
    • 
          com.sun.messaging.mq
          imqxm
          4.6-b01
      
      
          javaee
          javaee-api
          5
      
      
          xalan
          xalan
          2.7.0
      
      
          com.sun.messaging.mq
          jaxm-api
          4.6-b01
                  
      
    • JMS message sender (Embedded SoapMessage with Attachment)
    • import com.google.common.io.Files;
      import com.sun.messaging.xml.MessageTransformer;
      
      import javax.activation.DataHandler;
      import javax.activation.FileDataSource;
      import javax.jms.*;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.xml.soap.*;
      import java.io.File;
      import java.io.IOException;
      import java.nio.charset.Charset;
      import java.util.Hashtable;
      
      public class MockWebServiceOverJMSSender {
          private static final String CONNECTION_FACTORY_JNDI_NAME = "weblogic.jms.XAConnectionFactory";
          private static final String QUEUE_JNDI_NAME = "jms/TestQueueJNDI";
      
          public static void sendMessage() {
              try {
                  QueueConnection connection = null;
                  QueueSession session = null;
                  QueueSender queueSender = null;
                  try {
                      Hashtable<String,String> properties = new Hashtable();
                      properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
                      properties.put(Context.PROVIDER_URL, "t3://localhost:7001");
      
                      InitialContext context = new InitialContext(properties);
                      QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup(CONNECTION_FACTORY_JNDI_NAME);
                      connection = connectionFactory.createQueueConnection();
                      session = connection.createQueueSession(false, 0);
                      Queue queue = (Queue) context.lookup(QUEUE_JNDI_NAME);
                      queueSender = session.createSender(queue);
      
                      MessageFactory messageFactory = MessageFactory.newInstance();
                      SOAPMessage soapMessage = messageFactory.createMessage();
                      soapMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
                      SOAPPart soapPart = soapMessage.getSOAPPart();
                      SOAPEnvelope envelope = soapPart.getEnvelope();
                      SOAPBody soapBody = envelope.getBody();
      
                      soapBody.setTextContent(buildSoapBodyContent());
      
                      AttachmentPart attachment = buildSoapAttachment(soapMessage);
                      soapMessage.addAttachmentPart(attachment);
      
                      soapMessage.saveChanges();
                      Message message = MessageTransformer.SOAPMessageIntoJMSMessage(soapMessage, session);
                      queueSender.send(message);
                  } finally {
                      queueSender.close();
                      session.close();
                      connection.close();
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  System.exit(0);
              }
          }
      
          private static String buildSoapBodyContent() throws IOException {
              String responseFile = "c:/temp/PoliceAVOApplicationResponse-Non-provisional.xml";
              return Files.toString(new File(responseFile), Charset.forName("UTF-8"));
          }
      
          private static AttachmentPart buildSoapAttachment(SOAPMessage soapMessage) {
              DataHandler dh = new DataHandler(new FileDataSource("c:/temp/test_avo.pdf"));
              return soapMessage.createAttachmentPart(dh);
          }
      
          public static void main(String args[]) {
              sendMessage();
          }
      
    • JMS consumer(parse message body & save attachment to disk)
    • import au.gov.nsw.police.nodi.common.IOHelper;
      import com.google.common.io.Files;
      import com.sun.messaging.xml.MessageTransformer;
      import org.w3c.dom.Document;
      import org.xml.sax.SAXException;
      
      import javax.jms.*;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;
      import javax.xml.parsers.ParserConfigurationException;
      import javax.xml.soap.*;
      import javax.xml.xpath.*;
      import java.io.ByteArrayInputStream;
      import java.io.File;
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.Date;
      import java.util.Hashtable;
      import java.util.Iterator;
      
      public class MockJMSMessageConsumer {
          private static final String CONNECTION_FACTORY_JNDI_NAME = "weblogic.jms.XAConnectionFactory";
          private static final String QUEUE_JNDI_NAME = "jms/TestQueueJNDI";
      
          private static void consumeMessage() {
              try {
                  QueueConnection connection = null;
                  QueueSession session = null;
                  QueueReceiver queueReceiver = null;
                  try {
                      Hashtable<String, String> properties = new Hashtable();
                      properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
                      properties.put(Context.PROVIDER_URL, "t3://localhost:7001");
      
                      InitialContext context = new InitialContext(properties);
                      QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup(CONNECTION_FACTORY_JNDI_NAME);
                      connection = connectionFactory.createQueueConnection();
                      session = connection.createQueueSession(false, 0);
                      Queue queue = (Queue) context.lookup(QUEUE_JNDI_NAME);
                      queueReceiver = session.createReceiver(queue);
                      connection.start();
      
                      while (true) {
                          Message message = queueReceiver.receive(1);
                          MessageFactory messageFactory = MessageFactory.newInstance();
      
                          if (message != null) {
                              SOAPMessage soapMessage = MessageTransformer.SOAPMessageFromJMSMessage(message, messageFactory);
                              onMessage(soapMessage);
                          }
                      }
                  } finally {
                      queueReceiver.close();
                      session.close();
                      connection.close();
                  }
              } catch (Exception e) {
                  e.printStackTrace(System.err);
                  System.exit(0);
              }
          }
      
          private static void onMessage(SOAPMessage soapMessage) {
              try {
                  System.out.println("Start to processing message from ESB...");
                  SOAPBody soapBody = soapMessage.getSOAPPart().getEnvelope().getBody();
      
                  Iterator iterator = soapMessage.getAttachments();
                  if (iterator.hasNext()) {
                      AttachmentPart attachmentPart = (AttachmentPart) iterator.next();
                      System.out.println("here");
                      parseMetadataFromSoapMessage(soapBody, attachmentPart);
                  }
                  System.out.println("Finish to processing message from ESB");
              } catch (Throwable e) {
                  e.printStackTrace();
              }
          }
      
      
          private static void parseMetadataFromSoapMessage(SOAPBody soapBody, AttachmentPart attachmentPart) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException, SOAPException {
              String content = soapBody.getTextContent();
              Document doc = buildDocumentFromString(content);
      
              XPath xPath = createXPath();
              String courtReferenceNumber = getStringValueWithGiveXPath(xPath, doc, "/n1:PublishDocumentMessage/@ProceedingNumber");
              String courtName = getStringValueWithGiveXPath(xPath, doc, "/n1:PublishDocumentMessage/n1:Listing/Court/@Name");
              String eventNumber = getStringValueWithGiveXPath(xPath, doc, "/n1:PublishDocumentMessage/n1:QuestionsAndAnswers/n1:DataField[@Name='IDF POLAPPEVENTNO']/@Value");
              String cni = getStringValueWithGiveXPath(xPath, doc, "/n1:PublishDocumentMessage/n1:Participant[n1:ParticipantID[@ParticipantRole='DEFENDANT']]/n1:CrimeIndividual/common:IndividualDetails/@CNI");
              System.out.println("court reference number: " + courtReferenceNumber);
              System.out.println("court name: " + courtName);
              System.out.println("event number: " + eventNumber);
              System.out.println("cni: " + cni);
      
              saveAttachmentToDisk(attachmentPart);
          }
      
          private static Document buildDocumentFromString(String content) throws ParserConfigurationException, SAXException, IOException {
              DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
              docBuilderFactory.setNamespaceAware(true);
              DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
              InputStream inputStream = new ByteArrayInputStream(content.getBytes());
              return docBuilder.parse(inputStream);
          }
      
          private static XPath createXPath() {
              XPathFactory xPathfactory = XPathFactory.newInstance();
              XPath xpath = xPathfactory.newXPath();
              xpath.setNamespaceContext(new AVONamespaceContext());
      
              return xpath;
          }
      
          private static String getStringValueWithGiveXPath(XPath xpath, Document document, String expression) throws XPathExpressionException {
              XPathExpression xPathExpression = xpath.compile(expression);
              return (String) xPathExpression.evaluate(document, XPathConstants.STRING);
          }
      
          private static void saveAttachmentToDisk(AttachmentPart attachmentPart) throws IOException, SOAPException {
              byte[] pdfFile= IOHelper.readInputStream(attachmentPart.getDataHandler().getInputStream());
              Date now = new Date();
              Files.write(faxImages, new File("c:/temp/" + now.getTime() + ".pdf"));
          }
      
          public static void main(String args[]) {
              consumeMessage();
          }
      
    • help class
    • import javax.xml.XMLConstants;
      import javax.xml.namespace.NamespaceContext;
      import java.util.Iterator;
      
      public class AVONamespaceContext implements NamespaceContext {
          public String getNamespaceURI(String prefix) {
              if (prefix == null) throw new NullPointerException("Invalid Namespace Prefix");
              else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
                  return "http://www.w3.org/2001/XMLSchema-instance";
              } else if ("n1".equals(prefix)) {
                  return "http://cats.agd.nsw.gov.au/PublishDocumentMessage/v1_0";
              } else if ("common".equals(prefix)) {
                  return "http://cats.agd.nsw.gov.au/DocumentLodgementInterfaces/Common/v1_0";
              } else if ("cim".equals(prefix)) {
                  return "http://cim.justicesector.nsw.gov.au/Common/1";
              } else if ("as4590".equals(prefix)) {
                  return "http://cim.justicesector.nsw.gov.au/as459";
              } else {
                  return XMLConstants.NULL_NS_URI;
              }
          }
      
          public String getPrefix(String namespaceURI) {
              return null;
          }
      
          public Iterator getPrefixes(String namespaceURI) {
              return null;
          }
      }
      
    • Another Solution
    • You don't need to dependent the above dependencies. You just implement your own transformer. My sample as follow:
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      import javax.jms.BytesMessage;
      import javax.jms.JMSException;
      import javax.jms.Message;
      import javax.jms.Session;
      import javax.xml.messaging.JAXMException;
      import javax.xml.soap.*;
      import java.io.*;
      import java.util.Enumeration;
      import java.util.Hashtable;
      import java.util.Iterator;
      
      import static com.google.common.base.Throwables.getStackTraceAsString;
      
      /**
       * The Rcode>Transformer</code> class encapsulates the functionality
       * to transform SOAP and JMS messages.
       */
      public class MessageTransformer {
          private static final Logger log = LoggerFactory.getLogger(MessageTransformer.class);
          private MessageTransformer() {
          }
      
          /**
           * Transforms a <code>javax.xml.soap.SOAPMessage</code> message
           * into a <code>javax.jms.Message</code> message.
           *
           * @param soapMessage the SOAPMessage to be converted to the JMS Message.
           * @param session     The JMS Session to be used to construct the JMS Message.
           * @throws JAXMException If any error is encountered when transforming the message.
           */
          public static Message SOAPMessageIntoJMSMessage(SOAPMessage soapMessage, Session session) throws JAXMException {
              try {
                  /**
                   * Construct a bytes message object.
                   * This is to make sure the utility works across all vendors.
                   */
                  BytesMessage bytesMessage = session.createBytesMessage();
      
                  /**
                   * This is here to make sure that RI's bad SOAP implementation
                   * will get updated for internal buffers.
                   */
                  soapMessage.saveChanges();
      
                  writeMimeHeaders(soapMessage, bytesMessage);
                  writeSOAPBody(soapMessage, bytesMessage);
      
                  return bytesMessage;
              } catch (JAXMException JAXMe) {
                  throw JAXMe;
              } catch (Exception e) {
                  log.error(getStackTraceAsString(e));
                  throw new JAXMException(e);
              }
          }
      
          private static void writeMimeHeaders(SOAPMessage soapMessage, BytesMessage bytesMessage) throws Exception {
              MimeHeaders mimeHeaders = soapMessage.getMimeHeaders();
              Hashtable hashtable = convertMimeHeadersToHashtable(mimeHeaders);
      
              ByteArrayOutputStream mimeOut = writeHashtableToByteArrayOutputStream(hashtable);
      
              byte[] mimeHeadersBytes = mimeOut.toByteArray();
              int mimeHeadersLength = mimeHeadersBytes.length;
              bytesMessage.writeInt(mimeHeadersLength);
              bytesMessage.writeBytes(mimeHeadersBytes);
              mimeOut.close();
              log.debug("SOAP to JMS mime headers length: {}", mimeHeadersLength);
          }
      
          /**
           * Convert MimeHeaders to Hashtable.  The hashtable is then used to write
           * to JMS BytesMessage.
           */
          private static Hashtable convertMimeHeadersToHashtable(MimeHeaders mimeHeaders) {
              Hashtable hashtable = new Hashtable();
              Iterator it = mimeHeaders.getAllHeaders();
              while (it.hasNext()) {
                  MimeHeader mimeHeader = (MimeHeader) it.next();
                  hashtable.put(mimeHeader.getName(), mimeHeader.getValue());
              }
      
              return hashtable;
          }
      
          private static ByteArrayOutputStream writeHashtableToByteArrayOutputStream(Hashtable hashtable) throws IOException {
              ByteArrayOutputStream mimeOut = new ByteArrayOutputStream();
              ObjectOutputStream objectOutputStream = new ObjectOutputStream(mimeOut);
              objectOutputStream.writeObject(hashtable);
              objectOutputStream.flush();
              objectOutputStream.close();
              return mimeOut;
          }
      
          private static void writeSOAPBody(SOAPMessage soapMessage, BytesMessage bytesMessage) throws Exception {
              ByteArrayOutputStream bodyOutput = new ByteArrayOutputStream();
              soapMessage.writeTo(bodyOutput);
      
              byte[] bodyBytes = bodyOutput.toByteArray();
              int bodyLength = bodyBytes.length;
              bytesMessage.writeInt(bodyLength);
              bytesMessage.writeBytes(bodyBytes);
      
              bodyOutput.close();
              log.debug("SOAP to JMS body length: {}", bodyLength);
          }
      
      
          /**
           * Extracts a <code>javax.xml.soap.SOAPMessage</code> object from the
           * <code>javax.jms.Message</code> object into which it was transformed
           * using the <code>SOAPMessageIntoJMSMessage</code> method.
           * <p/>* The <code>MessageFactory</code> parameter is used to construct the
           * <code>javax.xml.soap.SOAPMessage</code> object.
           * <p/>* If <code>MessageFactory</code> is <code>null</code> then the
           * default SOAP MessageFactory will be used to construct the
           * SOAP message.
           *
           * @param message        The JMS message from which the SOAP message is to be extracted.
           * @param messageFactory The SOAP MessageFactory to be used to contruct the SOAP message.
           * @throws JAXMException If any error is encountered when extracting the message.
           */
          public static SOAPMessage extractSOAPMessageFromJMSMessage(Message message, MessageFactory messageFactory) throws JAXMException {
              BytesMessage bytesMessage = (BytesMessage) message;
              try {
                  MimeHeaders mimeHeaders = readMimeHeaders(bytesMessage);
                  ByteArrayInputStream bodyByteArrayInputStream = readSoapBodyToByteArrayInputStream(bytesMessage);
      
                  return constructSoapMessage(messageFactory, mimeHeaders, bodyByteArrayInputStream);
              } catch (Exception e) {
                  throw new JAXMException(e);
              }
          }
      
          private static MimeHeaders readMimeHeaders(BytesMessage bytesMessage) throws JMSException, IOException, ClassNotFoundException {
              int mimeHeadersLength = bytesMessage.readInt();
              byte[] mimeHeadersBytes = new byte[mimeHeadersLength];
              bytesMessage.readBytes(mimeHeadersBytes, mimeHeadersLength);
      
              ByteArrayInputStream mimeHeadersByteArrayInputStream = new ByteArrayInputStream(mimeHeadersBytes);
              ObjectInputStream objectInputStream = new ObjectInputStream(mimeHeadersByteArrayInputStream);
              Hashtable hashtable = (Hashtable) objectInputStream.readObject();
              return convertHashtableToMimeHeaders(hashtable);
          }
      
          private static MimeHeaders convertHashtableToMimeHeaders(Hashtable hashtable) {
              MimeHeaders mimeHeaders = new MimeHeaders();
      
              Enumeration enm = hashtable.keys();
              while (enm.hasMoreElements()) {
                  Object key = enm.nextElement();
                  mimeHeaders.addHeader((String) key, (String) hashtable.get(key));
                  log.debug("mime-header: {} = {}", key, hashtable.get(key));
              }
      
              return mimeHeaders;
          }
      
          private static ByteArrayInputStream readSoapBodyToByteArrayInputStream(BytesMessage bytesMessage) throws JMSException {
              int bodyLength = bytesMessage.readInt();
              byte[] buf = new byte[bodyLength];
              bytesMessage.readBytes(buf, bodyLength);
      
              return new ByteArrayInputStream(buf);
          }
      
          private static SOAPMessage constructSoapMessage(MessageFactory messageFactory, MimeHeaders mimeHeaders,
                                                          ByteArrayInputStream bodyByteArrayInputStream) throws SOAPException, IOException {
              if (messageFactory == null) {
                  messageFactory = getMessageFactory();
              }
      
              return messageFactory.createMessage(mimeHeaders, bodyByteArrayInputStream);
          }
      
          private static MessageFactory getMessageFactory() throws SOAPException {
              return MessageFactory.newInstance();
          }
      }
      
    • reference
    • SOAP over Java Message Service 1.0

    Create xml Document from File or String & convert Document to String

    • Create xml Document from File or String
    • public Document buildDocumentFromExternalResource() throw Exception {
          String content = "....";
          DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
          docBuilderFactory.setNamespaceAware(true);
          DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
          InputStream inputStream = new ByteArrayInputStream(content.getBytes());
          Document doc = docBuilder.parse(inputStream);
          // read from file
          doc = docBuilder.parse(new File("c:/temp/myContent.xml"));
      }
      
    • convert Document to String
    • public String convertDocumentToString(SOAPBody soapBody) throw Excepiton {
              Document doc = soapBody.getOwnerDocument();
              Source source = new DOMSource(doc);
              StringWriter out = new StringWriter();
              Result result = new StreamResult(out);
      
              TransformerFactory transformerFactory = TransformerFactory.newInstance();
              Transformer transformer = transformerFactory.newTransformer();
              transformer.transform(source, result);
      
              String content = out.toString();
         }
      

    Monday, 9 July 2012

    Regular express validate date time

    reference:
    http://stackoverflow.com/questions/1315376/regular-expression-for-date-time-format-mm-dd-yy-hhmmss-am-pm-in-asp-net-reg


    RegEx for matching all dates, including leap years.
    1. For DD-MM-YYYY format
    2. ^(?:31#(?:(?:0[13578])|(?:1[02]))#)|(?:(?:29|30)#(?:(?:0[1,3-9])|(?:1[0-2]))#)(?:(?:1[6-9]|[2-9]\d)\d{2})$|^(?:29#02#(?:(?:(?:1[6-9]|[2-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0[1-9])|(?:1\d)|(?:2[0-8]))#(?:(?:0[1-9])|(?:1[0-2]))#(?:(?:1[6-9]|[2-9]\d)\d{2})$
      
    3. For MM-DD-YYYY format
    4. ^(?:(?:(?:0?[13578]|1[02])#31)\1|(?:(?:0?[1,3-9]|1[0-2])#(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2#29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))#(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
      
    5. Java Code
    6. String inputDate;
      String regex="^(?:31/(?:(?:0[13578])|(?:1[02]))/)|(?:(?:29|30)/(?:(?:0[1,3-9])|(?:1[0-2]))/)(?:(?:1[6-9]|[2-9]\\d)\\d{2})$|^(?:29/02/(?:(?:(?:1[6-9]|[2-9]\\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0[1-9])|(?:1\\d)|(?:2[0-8]))/(?:(?:0[1-9])|(?:1[0-2]))/(?:(?:1[6-9]|[2-9]\\d)\\d{2})$";
      Pattern pattern = Pattern.compile(inputDate);
      Matcher matcher = pattern.matcher(inputDate);
      boolean found = matcher.matches();
      
    7. For Time
    8. ^([0|1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$
      

    Friday, 2 March 2012

    get directory of current class in java

    URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
    String path = URLDecoder.decode(url.getPath(), "utf-8"); //important: if directory has space or chinese words
    File file= new File(path);
    System.out.println("directory is: " + file.getPath());
    

    Convert file path to URL and vice verse in java

    1 URL --> File path
    URL url = ...;
    File f = new File(url.getPath());
    

    2. File Path to url
    File f =...;
    
    URI uri = file.toURI();
    URL url = uri.toURL();
    

    Wednesday, 29 February 2012

    How to mock http servlet with jetty to test some http-post,http-get in unit test?

    Solution:
    1. Write you own mock servlet
    public class MockServlet extends HttpServlet {
        private String servletData;
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            contextService(req, resp);
        }
    
        @Override
        protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    
        private void contextService(HttpServletRequest req, HttpServletResponse resp)  throws ServletException, IOException {
            servletData = IOUtils.toString(req.getInputStream());
    
            resp.setContentType("text/html");
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.getWriter().print("Response from mock server: Submit is success.");
        }
    
        public String getServletData() {
            return servletData;
        }
    }
    

    2. define mock beans in spring application context (servlet and jetty server)
    2.1 servlet:

    <bean id="mockServlet" class="my.MockServlet"/>
    

    2.2 jetty server
    
            
                
                    
                        <property name="host" value="localhost"/>
                        <property name="port" value="8900"/>
                    
                
            
            
                
                    
                        <property name="contextPath" value="/"/>
                        
                            <bean class="org.mortbay.jetty.servlet.SessionHandler">
                        
                        <property name="resourceBase" value="c:/temp"/>
                        
                            
                                
                                
                                    
                                        
                                        
                                            <property name="name" value="defaultServlet"/>
                                            
                                                <bean class="org.mortbay.jetty.servlet.DefaultServlet"/>
                                            
                                            
                                                
                                                    <entry key="resourceBase" value="./"/>
                                                
                                            
                                        
                                        
                                            <property name="name" value="mockServlet"/>
                                            <property name="servlet" ref="mockServlet"/>
                                            
                                                
                                                    <entry key="resourceBase" value="./"/>
                                                
                                            
                                        
                                    
                                
                                
                                    
                                        
                                            
                                                
                                                    /
                                                
                                            
                                            <property name="servletName" value="defaultServlet"/>
                                        
                                        
                                            
                                                
                                                    /test/myAction
                                                
                                            
                                            <property name="servletName" value="mockCharityServlet"/>
                                        
                                    
                                
                            
                        
                    
                    
                    
                
            
        
    


    3. You Http Client code

    final HttpPost post = new HttpPost("http://127.0.0.1:9800/test/myAction");
    final HttpResponse resp = hc.execute(post);
    final HttpEntity respContent = resp.getEntity();
    final InputStream is = respContent.getContent();
    final StringWriter strWr = new StringWriter();
    IOUtils.copy(is, strWr);
    return strWr.toString();
    

    4. Junit
    String expected = "Response from mock server: Submit is success.";
    String actual = mockClient.submit();
    assertEquals(expected, actual);
    

    How to test email of junit

    How can it test email of junit? Solution use dumbster as a fake smtp server 1. add dependency to pom.xml
    
        dumbster
        dumbster
        1.6
        test
    
    
    2. add bean definition to spring applicationContext.xml
    
        <constructor-arg index="0" value="2525"/>
    
    
    using javax mail session
    
        
            
                127.0.0.1
                2525
            
        
    
    
        <constructor-arg ref="mailSession" type="javax.mail.Session"/>
    
    
    or if you using spring mail sender:
    <bean class="org.springframework.mail.javamail.JavaMailSenderImpl" id="mailSender" p:host="localhost" p:port="2525"/>
    
    3. define one util class
    import com.dumbster.smtp.SimpleSmtpServer;
    import com.dumbster.smtp.SmtpMessage;
    import com.dumbster.smtp.SmtpResponse;
    import com.dumbster.smtp.SmtpState;
    import org.hamcrest.Description;
    import org.hamcrest.Factory;
    import org.hamcrest.Matcher;
    import org.hamcrest.TypeSafeMatcher;
    
    import java.util.Iterator;
    
    public class BodySmtpMessage extends TypeSafeMatcher<Smtpmessage> {
        private SmtpMessage smtpMessage;
    
        public BodySmtpMessage(SmtpMessage smtpMessage) {
            this.smtpMessage = smtpMessage;
        }
    
        @Override
        public boolean matchesSafely(SmtpMessage smtpMessage) {
            return smtpMessage.getBody().equals(smtpMessage.getBody());
        }
    
        @Override
        public void describeTo(Description description) {
            description.appendText("not same body message");
        }
    
        @Factory
        public static <T> Matcher<smtpmessage> bodyEqualTo(SmtpMessage smtpMessage) {
            return new BodySmtpMessage(smtpMessage);
        }
    
        public static SmtpMessage getExpectedSmtpMessage(String body) {
            SmtpResponse smtpResponse = new SmtpResponse(1, "", SmtpState.DATA_BODY);
            SmtpMessage expectedMessage = new SmtpMessage();
            expectedMessage.store(smtpResponse, body);
    
            return expectedMessage;
        }
    
        public static SmtpMessage getFirstReceivedMessage(SimpleSmtpServer simpleSmtpServer) {
            Iterator<smtpmessage> receivedEmail = simpleSmtpServer.getReceivedEmail();
    
            while (receivedEmail.hasNext()) {
                return receivedEmail.next();
            }
            return null;
        }
    }
    
    4. Junit
    import com.dumbster.smtp.SimpleSmtpServer;
    import com.dumbster.smtp.SimpleSmtpServer;
    import com.dumbster.smtp.SmtpMessage;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    
    import static au.com.hothouse.toyota.utils.email.BodySmtpMessage.*;
    import static org.hamcrest.CoreMatchers.is;
    import static org.junit.Assert.*;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = "classpath*:applicationContext-test.xml")
    public class TestEmailerImpl {
        @Resource(name = "saveYourCarEmailer")
        private EmailerImpl emailer;
        @Resource(name = "fakeSmtpServer")
        private SimpleSmtpServer simpleSmtpServer;
    
        private static String EXPECTED = "Dear Jianjun Shou,\n" +
                "\n" +
                "Here is the permanent link to the vehicle you have created:\n" +
                "\n" +
                "http://test.email.hothouse.com.au\n" +
                "\n" +
                "Thank you for vising the Toyota website.\n" +
                "\n" +
                "Regards,\n" +
                "\n" +
                "The Toyota Team";
    
        @Test
        public void testEmail() throws Exception {
            emailer.email("Jianjun", "Shou", "sean.shou@hothouse.com.au", "http://test.email.hothouse.com.au");
            assertTrue("test failed", simpleSmtpServer.getReceivedEmailSize() > 0);
            SmtpMessage sentMessage = getFirstReceivedMessage(simpleSmtpServer);
            SmtpMessage expectedSmtpMessage = getExpectedSmtpMessage(EXPECTED);
            assertThat(sentMessage, is(bodyEqualTo(expectedSmtpMessage)));
        }
    }
    

    Friday, 17 February 2012

    How to enable jmx on tomcat in linux

    create setenv.sh in $CATALINA_HOME/bin, add following lines to here

    CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.4.38"
    


    Important!: don't forget to give quote(")