Wednesday, February 16, 2011

log4j notes

Do not use e.printStackTrace

e.printStackTrace prints to the console. You will only see this messages, if you have defined a console appender. If you use Tomcat or other application server with a service wrapper and define a console appender, you will blow up your wrapper.log.
try {
     ......... snip .......
 } catch ( SomeException e) {
     e.printStackTrace();
 }
You can use log.error(e,e). The second parameter passed an exception and will print the stack trace into the logfile.
try {
     ......... snip .......
 } catch (SomeException e) {
     log.error("Exception Message", e);
   // display error message to customer
 }

Wednesday, February 9, 2011

How To Integrate GWT (GWT-EXT) and JasperReports

How To Integrate GWT (GWT-EXT) and JasperReports

First part, why reports?


You are enthusiastic researcher of new technologies, freelancer and now you are developing an corporate solution, based on Google Web Toolkit (GWT). And once, your lovely customer call to you at one at night, and asking you about new features he wants – reports and asking you to meet tomorrow morning and discuss about it! Op… Ok, he is also promising to you free coffee and inviting you to the private party … so you agreed

You are angry, what the f… it is… reports? Why? There is so nice gwt-ext panel, buttons, windows …. But, you always following the style of customer friendly behavior, so, you are deciding to make client happy

So, let’s start with a task definition.


Task Definition

We have a goal to create a prototype of report generation, viewing and exporting to the different file formats. Task is not so hard, but as well requires knowledge and some tricks to do it well. 

Requirements to accomplish task

To make an complete solution, you need to get and install next tools:
  1. Gwt (Gwt-Ext) application:)
Some facts about JasperReports 


JasperReports is one of the most popular Open Source libraries for a report generation. It has a good possibilities for integration with java applications.



Reports definitions is a plain XML files, so it allows in the future to create new reports, using a velocity template engine(http://velocity.apache.org/), Jelly (http://commons.apache.org/jelly/) or other template tools. Report definition files has an extension: *.jrxml.

After you are created a definition, it compiles and you are getting a *.jasper files.


JasperCompileManager.compileReportToFile("WebappReport.jrxml");

Some cases it is convenient, since it allows to hide definitions from customer, by giving him an compiled report, but not the sources.

After compilation is done, you should execute report using JasperFillManager.fillReport() to get JasperPrint object (you can then store it to the file).

Actually, you already got an report and can use it! You can use a wide collection of exporters to export it to any format you like: JexcelApiExporter, JexcelApiExporterNature, JexcelApiExporterParameter, JRCsvExporter, JRGraphics2Dexporter, JRHtmlExporter, JRPdfExporter, JRPrintServiceExporter, JRRtfExporter, JRTextExporter, JRXlsExporter, JRXmlExporter.

Application prototype 

For a prototype of an application I took GWT-Ext Showcase2 and changed it, to accomplish the customer needs.


When you are clicking “Logined users”, information is opened in new tab, showing a details. Everything is clear, isn’t? So, continue step by step. 
Step One

So, let’s start with Jasper and create report.
  • We have jasperreports-3.1.2-project.zip, extract it to C:\demo\jasper. And at folder “demo\samples\webapp” we should to find report WebappReport.jrxml (great example for report running under the web)
  • Than, using iReport changing report, making it looks nice: put logo of company, change a title and configuring JDBC DataSource and Report Query.



  • Necessary changes in servlets
    “demo\samples\webapp\WEB-INF\classes\servlets” – making possible to start a report using parameter ‘reportfile’:
    String rp = req.getParameter(“reportfile”);
    String reportFileName = context.getRealPath("/reports/”+rp+”.jasper");
    “demo\samples\webapp” for testing – in HTML all links changing to “?reportfile=WebappReport”;
  • At root folder “ demo\samples\webapp” we need to run ANT.


After we need a little bit to configure Tomcat, coping content “demo\samples\webapp” to the Tomcat ”webapps\jasper” and run it.


Than easy step: open a browser and go to url: (be careful, your port number can be different)
http://localhost:8887/jasper/

It should be like above. Great job, it works!

Second step

So, we have a working report, and now we want to run it using gwt application. The sample application should be like this:


Let’s integrate GWT and Jasper together!
Creating an simplest ReportManager class with static methods:
public class ReportManager {
public static String getExportReportURL(String report, String exptype){
return "http://localhost:8887/jasper/servlets/"+exptype+"?reportfile=" + report;
};

}
Than, we should to create an Panel:

Panel centerPanel = new Panel();
centerPanel.setLayout(new BorderLayout());
centerPanel.setTitle("Sessions");


String rep_url = ReportManager.getExportReportURL("WebappReport","html");
final Frame frame = new Frame(rep_url);
centerPanel.add(frame, new BorderLayoutData(RegionPosition.CENTER));

Toolbar toolbar = new Toolbar();
toolbar.addFill();
ToolbarButton toolbarButton = new ToolbarButton("PDF", new ButtonListenerAdapter() {
public void onClick(Button button, EventObject e) {
frame.setUrl(ReportManager.getExportReportURL("WebappReport","pdf"));
}
});


Run a project in Host Mode, clicking to the button “Logined users” and .... Oppa! 

If you want to see it in pdf, just click to the button export to “PDF”


So, everything you need now… sleep, meet with a client and with cup of tea share with him great perspectives of his business :)

gwt for mutiple uplad file and send email

Gwt upload multiple files using muti upload and Servlet.
Email with multiple file attachment, first servlet can be used for file uploading, then rpc can be used for send email.
Tips: use  a uuid to identify an email session.



@Override
public String SendMailService(String uuid, String to, String subject,
String body) {
System.out.println(uuid+" " + to + " " + subject + " " + body);
// TODO Auto-generated method stub
String from = "benma@google.com";
String host = "mail.google.com";
String fileDir = "c:\\myupload\\"+uuid;
String recipients[] = to.split(";");
// create some properties and get the default Session
 Properties props = System.getProperties();
 props.put("mail.smtp.host", host);

 Session session = Session.getInstance(props, null);
 session.setDebug(true);
 try
 {
     // create a message
     MimeMessage msg = new MimeMessage(session);
   
     msg.setFrom(new InternetAddress(from));
   
//      InternetAddress[] address = {new InternetAddress(to)};
//      msg.setRecipients(Message.RecipientType.TO, address);
   
     InternetAddress[] addressTo = new InternetAddress[recipients.length];
     for (int i = 0; i < recipients.length; i++){
         addressTo[i] = new InternetAddress(recipients[i]);
     }
     msg.setRecipients(Message.RecipientType.TO, addressTo);
   
     msg.setSubject(subject);

     // create and fill the first message part
     MimeBodyPart mbp1 = new MimeBodyPart();
     mbp1.setText(body);

  // create the Multipart and add its parts to it
     Multipart mp = new MimeMultipart();
     mp.addBodyPart(mbp1);
   
     Vector<String> vecNames = getFileNames(fileDir);
     for(String filename : vecNames) {
     // create the second message part
     MimeBodyPart mbp2 = new MimeBodyPart();
     // attach the file to the message
     FileDataSource fds = new FileDataSource(filename);
     mbp2.setDataHandler(new DataHandler(fds));
     mbp2.setFileName(fds.getName());
     mp.addBodyPart(mbp2);
     }

     // add the Multipart to the message
     msg.setContent(mp);
     // set the Date: header
     msg.setSentDate(new Date());
     // send the message
     Transport.send(msg);
 }
 catch (Exception mex) {
     mex.printStackTrace();
     return "Mail NOT successfully.";
 }
return "Your mail has been sent successfuly.";
}

Tuesday, February 8, 2011

Getting a Request Parameter in a Servlet

In a GET request, the request parameters are taken from the query string (the data following the question mark on the URL). For example, the URL http://hostname.com?p1=v1&p2=v2 contains two request parameters – – p1 and p2. In a POST request, the request parameters are taken from both query string and the posted data which is encoded in the body of the request. This example demonstrates how to get the value of a request parameter in either a GET or POST request.
// See also The Quintessential Servlet

// This method is called by the servlet container to process a GET request.
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    doGetOrPost(req, resp);
}

// This method is called by the servlet container to process a POST request.
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    doGetOrPost(req, resp);
}

// This method handles both GET and POST requests.
private void doGetOrPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    // Get the value of a request parameter; the name is case-sensitive
    String name = "param";
    String value = req.getParameter(name);
    if (value == null) {
        // The request parameter 'param' was not present in the query string
        // e.g. http://hostname.com/?a=b
    } else if ("".equals(value)) {
        // The request parameter 'param' was present in the query string but has no value
        // e.g. http://hostname.com/?param=&a=b
    }

    // The following generates a page showing all the request parameters
    PrintWriter out = resp.getWriter();
    resp.setContentType("text/plain");

    // Get the values of all request parameters
    Enumeration enum = req.getParameterNames();
    for (; enum.hasMoreElements(); ) {
        // Get the name of the request parameter
        name = (String)enum.nextElement();
        out.println(name);

        // Get the value of the request parameter
        value = req.getParameter(name);

        // If the request parameter can appear more than once in the query string, get all values
        String[] values = req.getParameterValues(name);

        for (int i=0; i<values.length; i++) {
            out.println("    "+values[i]);
        }
    }
    out.close();
}

UUIDs for GWT

http://www.2ality.com/2009/01/uuids-for-gwt.html
UUIDs are useful for many purposes, one of them is generating unique URIs for semantic web applications. Alas, under GWT, java.util.UUID is server-side only, so I looked for a client-side alternative. After some googling, I've found a nice JavaScript implementation, translated it to Java and can now use it with GWT. I'm publishing it here (with the consent of the original author), in case others find it useful.

package de.hypergraphs.hyena.core.shared.data;
/*
File: Math.uuid.js
Version: 1.3
Change History:
  v1.0 - first release
  v1.1 - less code and 2x performance boost (by minimizing calls to Math.random())
  v1.2 - Add support for generating non-standard uuids of arbitrary length
  v1.3 - Fixed IE7 bug (can't use []'s to access string chars.  Thanks, Brian R.)
  v1.4 - Changed method to be "Math.uuid". Added support for radix argument.  Use module pattern for better encapsulation.
Latest version:   http://www.broofa.com/Tools/Math.uuid.js
Information:      http://www.broofa.com/blog/?p=151
Contact:          robert@broofa.com
----
Copyright (c) 2008, Robert Kieffer
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    * Neither the name of Robert Kieffer nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public class UUID {
 private static final char[] CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
 /**
  * Generate a random uuid of the specified length. Example: uuid(15) returns
  * "VcydxgltxrVZSTV"
  *
  * @param len
  *            the desired number of characters
  */
 public static String uuid(int len) {
  return uuid(len, CHARS.length);
 }
 /**
  * Generate a random uuid of the specified length, and radix. Examples:
  * <ul>
  * <li>uuid(8, 2) returns "01001010" (8 character ID, base=2)
  * <li>uuid(8, 10) returns "47473046" (8 character ID, base=10)
  * <li>uuid(8, 16) returns "098F4D35" (8 character ID, base=16)
  * </ul>
  *
  * @param len
  *            the desired number of characters
  * @param radix
  *            the number of allowable values for each character (must be <=
  *            62)
  */
 public static String uuid(int len, int radix) {
  if (radix > CHARS.length) {
   throw new IllegalArgumentException();
  }
  char[] uuid = new char[len];
  // Compact form
  for (int i = 0; i < len; i++) {
   uuid[i] = CHARS[(int)(Math.random()*radix)];
  }
  return new String(uuid);
 }
 /**
  * Generate a RFC4122, version 4 ID. Example:
  * "92329D39-6F5C-4520-ABFC-AAB64544E172"
  */
 public static String uuid() {
  char[] uuid = new char[36];
  int r;
  // rfc4122 requires these characters
  uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
  uuid[14] = '4';
  // Fill in random data.  At i==19 set the high bits of clock sequence as
  // per rfc4122, sec. 4.1.5
  for (int i = 0; i < 36; i++) {
   if (uuid[i] == 0) {
    r = (int) (Math.random()*16);
    uuid[i] = CHARS[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
   }
  }
  return new String(uuid);
 }
}

How do I generate UUID / GUID?

UUID / GUID (Universally / Globally Unique IDentifier) are frequently use in programming. Some of its usage are for creating random file names, session id in web application, transaction id and for record's primary keys in database replacing the sequence or auto generated number.

import java.util.UUID;
public class RandomStringUUID {
    public static void main(String[] args) {
        //
        // Creating a random UUID (Universally unique identifier).
        //
        UUID uuid = UUID.randomUUID();
        String randomUUIDString = uuid.toString();

        System.out.println("Random UUID String = " + randomUUIDString);
        System.out.println("UUID version       = " + uuid.version());
        System.out.println("UUID variant       = " + uuid.variant());
    }
}

Monday, February 7, 2011

GWT menubar problem

If you mix gwt menubar with smartgwt tab in a tab set , it will have a problem.
Because gwt menubar will not show up, since the menuitem will have a lower z-index.

Solution:
When using smartgwt,
to create a menubar,
you should create a smartgwt menubar  in a smartgwt dialog.
It will work.