Code I/O

A topnotch WordPress.com site


4 Comments

5 Minutes on Adobe Flex – A tutorial on getting Flex and Java to process Microsoft Excel files …

In this 5 minute series, lets look into a scenario of uploading a Microsoft excel file to servlet parse it using Apache POI API to determine possible column type by sampling data in each column.

What you need?
Download Apache POI binaries from http://poi.apache.org/ and load it into your eclipse environment. Since this example uses Apache fileupload API’s, you’ll also require them from http://commons.apache.org/fileupload/

In a nutshell, the dependent libraries you need is as follows:
commons-fileupload.jar
commons-io.jar
log4j-1.2.15.jar
poi-3.2-FINAL-20081019.jar

Take an Excel file which has the following content (presuming the first row is always a header):
Sample Input spreadsheet

The following listing of CDS_Demo.mxml is to upload file to servlet and get back the columns and possible data type as result.  We’ll try to build more intelligence to find more use of these techniques. For now, the simple basics.

import mx.rpc.http.HTTPService;
			import mx.controls.Alert;
			private var fileReference:FileReference = new FileReference();
			private var FILE_UPLOAD_URL:String = "http://localhost:8080/cdss/upload";

			private function onImportFileButtonClick():void {
				doImportFile();
			}

			private function doImportFile():void
			{
				var fileFilter:FileFilter = new FileFilter("Data Files (*.txt; *.csv; *.xls)","*.txt;*.csv;*.xls");
	  			fileReference.browse([fileFilter]);
	  			fileReference.addEventListener(Event.SELECT,onFileSelect);
	  			fileReference.addEventListener(Event.COMPLETE,onFileComplete);
			}

			private function onFileSelect(event:Event):void
	  		{
	  			fileReference.load();
	  		}

	  		private function onFileComplete(event:Event):void
	  		{
	  			importFileName.text = fileReference.name;
	  		}

			private function onIOError(event:Event):void
			{
				Alert.show("Server is Down/Unreachable, Please try again later"
					, "Connection to Server Failed");
			}
			private function processReponse(event:DataEvent):void
	        {
	            var dataString:String = (event.data);
	            var xmlData:XML = XML(dataString);
	            var xmlList:XMLList = xmlData.children().children();
	            dataGrid.dataProvider = xmlList;
			}

			private function onParseFileButton():void
	  		{
				fileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, processReponse);
				fileReference.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
	  			fileReference.upload(new URLRequest(FILE_UPLOAD_URL));
	  		}

<mx:VBox height="100%"  verticalAlign="top">
 <mx:Spacer />
 <mx:HBox width="100%" verticalAlign="middle">
 <mx:Text  text="Select File" />
 <mx:TextInput id="importFileName" width="485" editable="false"/>
 <mx:Button id="importFileButton" label="..." click="onImportFileButtonClick()" width="36"/>
 <mx:Button id="parseFileButton" label="Suggest" click="onParseFileButton()"/>
 </mx:HBox>

 <mx:DataGrid id="dataGrid" width="672" height="50%">
 <mx:columns>
 <mx:DataGridColumn headerText="Column Name" dataField="@name" width="200"/>
 <mx:DataGridColumn headerText="Data Type" dataField="@type" width="100"/>
 <mx:DataGridColumn headerText="Sample" dataField="@value" width="100"/>
 </mx:columns>
 </mx:DataGrid>
 </mx:VBox>

The above code will get the response XML and display them in a datagrid. Once you get the idea on how to do this, you can play around with the API and explore more.

The following code illustrates how Apache POI, specifically HSSF API – I like the way it’s named “Horrible” 😉 Pun aside, I really appreciate how Apache has put this together to help developers work with hetrogenous environments and find solutions that will just work 🙂

This is how the web.xml looks

<servlet>
 <display-name>CDS upload service</display-name>
 <servlet-name>upload</servlet-name>
 <servlet-class>net.foss.cdss.service.FileUploaderServlet</servlet-class>

 <init-param>
 <param-name>net.foss.cdss.filestore</param-name>
 <param-value>C:/DEV/Temp/CDSS/FileStore</param-value>
 </init-param>

 <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
 <servlet-name>upload</servlet-name>
 <url-pattern>/upload</url-pattern>
 </servlet-mapping>

Here is the full source listings of servlet code:
FileUploaderServlet.java


package net.foss.cdss.service;

import java.io.IOException;
import java.util.Properties;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.foss.cdss.domain.Constants;
import net.foss.cdss.utils.FileUploader;
import net.foss.cdss.utils.FileUtils;

import org.apache.log4j.PropertyConfigurator;

public class FileUploaderServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static String fileStorePath = null;

public FileUploaderServlet() {
super();
}

public void init(ServletConfig config) throws ServletException {
super.init(config);

Properties loggingProperties = new Properties();
loggingProperties.setProperty(“log4j.rootLogger”, “debug, A1”);
loggingProperties.setProperty(“log4j.appender.A1”, “org.apache.log4j.ConsoleAppender”);
loggingProperties.setProperty(“log4j.appender.A1.layout”, “org.apache.log4j.PatternLayout”);
loggingProperties.setProperty(“log4j.appender.A1.layout.ConversionPattern”, “%d{ABSOLUTE} %5p %c{1}:%L – %m%n”);
PropertyConfigurator.configure(loggingProperties);

fileStorePath = (config.getInitParameter(Constants.FILESTORE_PATH));
if(null == fileStorePath) {
throw new ServletException(“Check web.xml init-param property for ” + Constants.FILESTORE_PATH + ” it is either missing or is not defined correctly”);
}

FileUtils.createNonExistantDirs(fileStorePath);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
FileUploader fileUploader = new FileUploader(request, response);
fileUploader.uploadFilesTo(fileStorePath);
}
}

Constants.java


package net.foss.cdss.domain;

public class Constants {
public static final String FILESTORE_PATH = “net.foss.cdss.filestore”;
}

MyFileUtils.java


package net.foss.cdss.utils;

import java.io.File;

public class MyFileUtils {
synchronized
public static boolean fileExists(String fileName){
File simpleFile = new File(fileName);
return(simpleFile.exists());
}

synchronized
public static void createNonExistantDirs(String dirName){
if(!fileExists(dirName)){
File dir = new File(dirName);
dir.mkdirs();
}
}

synchronized
public static void deleteDirectory(String dirName){
try
{
FileUtils.deleteDirectory(new File(dirName));
}
catch( Exception e ) {
}
}
}

FileUploader.java

package net.foss.cdss.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class FileUploader {
private static final Logger logger = Logger.getLogger(FileUploader.class.getName());

private String uuid = null;
private HttpServletRequest request = null;
private HttpServletResponse response = null;

public class ResponseData{
public String name;
public String type;
public String value;

public ResponseData(String name, String type, String value){
this.name = name;
this.type = type;
this.value = value;
}
}

public FileUploader(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;

this.uuid = UUID.randomUUID().toString();
}

@SuppressWarnings(“unchecked”)
public void uploadFilesTo(final String fileStorePath) throws ServletException, IOException {
try
{
List fileItems = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
if(fileItems == null){
logger.debug(“uploadFilesTo: No fileitems from client!”);

return;
}

Iterator fileIterator = fileItems.iterator();

while(fileIterator.hasNext())
{
FileItem fileItem = (FileItem)fileIterator.next();
if(fileItem == null){
logger.debug(“uploadFilesTo: null fileItem cannot be processed”);
return;
}

// definitely not a form item
if(!fileItem.isFormField()) {
String uploadPath = fileStorePath + File.separator + uuid;
MyFileUtils.createNonExistantDirs(uploadPath);
File fileWorkingOn = new File(uploadPath + File.separator + fileItem.getName());

if(fileWorkingOn == null){
logger.debug(“uploadFilesTo: File Path null!”);
}
else {
logger.debug(“uploadFilesTo: fileStorePath = ” + fileWorkingOn.getAbsolutePath());
fileItem.write(fileWorkingOn);

processFile(fileWorkingOn.getAbsolutePath());

MyFileUtils.deleteDirectory(uploadPath);
}
}
}
}
catch( Exception e ) {
logger.error(“uploadFilesTo: Exception during uploadFilesTo”);
e.printStackTrace();
}
}

private void sendResponse(HashMap hm){
Iterator iterator = hm.keySet().iterator();

StringBuffer buff = new StringBuffer();
buff.append(“”);

while(iterator.hasNext()) {
String key = iterator.next().toString();
ResponseData rd = hm.get(key);

buff.append(“” +
“”
+ “”);
}

buff.append(“”);
logger.debug(“xml = ” + buff);

response.setHeader(“Cache-Control”,”no-cache”);
response.setHeader(“Pragma”,”no-cache”);
response.setDateHeader(“Expires”, 0);
response.setContentType(“text/xml”);
try {
ServletOutputStream out = response.getOutputStream();
out.write(buff.toString().getBytes());
} catch (IOException e) {
logger.debug(“Exception obtaining outputstream”);
e.printStackTrace();
}

}
private void processFile(String fileName){
try {
FileInputStream fis = new FileInputStream(fileName);

// Treat input as Excel File
HSSFWorkbook wb = new HSSFWorkbook(fis);

// Take first sheet
HSSFSheet sheet = wb.getSheetAt(0);

// Read first row to sample data
HSSFRow headerRow = sheet.getRow(0);
HSSFRow dataRow = sheet.getRow(1); // Assuming data exists for sampling

HashMap pairs = new HashMap();

// Read each cell content and print it out.
for(int cellnum = 0; cellnum < headerRow.getLastCellNum(); cellnum++){
HSSFCell headerCell = headerRow.getCell(cellnum);
HSSFCell dataCell = dataRow.getCell(cellnum);

// Assume first row is always a header row
String colHeader = headerCell.getRichStringCellValue().toString();
logger.debug("row = " + headerRow.getRowNum() + " col = " + cellnum + " content = " + colHeader);

// Try different types
if(dataCell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
// Uses column header to determine if it’s date
if(colHeader.toLowerCase().contains(“date”)) {
String DATE_FORMAT = “dd-MM-yyyy”;
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
pairs.put(colHeader, new ResponseData(colHeader, “DATE”, “” +
sdf.format(dataCell.getDateCellValue())));
}
else {
pairs.put(colHeader, new ResponseData(colHeader, “NUMERIC”, “” + dataCell.getNumericCellValue()));
}
}
else if(dataCell.getCellType() == HSSFCell.CELL_TYPE_STRING){
pairs.put(colHeader, new ResponseData(colHeader, "STRING", dataCell.getRichStringCellValue().toString()));
}
else if(dataCell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN){
pairs.put(colHeader, new ResponseData(colHeader, "BOOLEAN", "" + dataCell.getBooleanCellValue()));
}
else {
pairs.put(colHeader, new ResponseData(colHeader, "UNDETERMINED", ""));
}
}

sendResponse(pairs);
} catch (FileNotFoundException e) {
logger.debug("File " + fileName + " does not exist!");
e.printStackTrace();
} catch (IOException e) {
logger.debug("IOException while reading " + fileName);
e.printStackTrace();
}
}
}

Once everything is working, here is the output that will be generated, hope this was fun for you …
Sample output

Advertisements


1 Comment

5 Minutes on Adobe Flex – Is flex for future web …

Adobe Flex is a lightweight cross-platform SDK, which enables the creation and deployment of rich-client applications. Flex is based on Adobe Flash, and with the addition of Flex Data Services, developers can integrate these rich clients with J2EE server side applications.

This document briefly outlines how Flex can offer a useful addition to the current enterprise application landscape.

Considerations

Consider the following routine developer requirements:

  • develop an enterprise/web application
  • expose the power of back-end functionality
  • provide a rich client that can deliver a ‘WOW’ factor

While these may be routine activities, the ongoing drive towards efficient and agile development means that there is a constant demand for better solutions.

If one takes a simple client-server architecture, a number of options are available.

Client-Server

Server Side

A variety of technology combinations are available on the server-side, from a fully Open Source stack like Linux-Apache-MySQL-PHP to vendor-specific proprietary implementations using Websphere, WebLogic, DB2, Oracle, SQLServer, etc.

These back-end solutions often provide powerful business solutions, but to truly empower end users, developers must provide an accessible and intuitive user interface.

Client Side

When implementing web application, frameworks such as Struts, JSF, Velocity or SpringMVC is handy.

AJAX gained a lot of popularity over time and it became the preferred way to provide rich user experience.  In combination with above frameworks and asynchronous communication tactics, the way your web application responds was transformed; however, there are certain limitations of AJAX:

JavaScript development tools: Since the advent of Internet in 1992, from static days, one has urged to see dynamic content and in 1995 JavaScript showed some promise.  But it’s over 15years now, but it has not gotten any good tools until Google’s GWT came out.  But for languages like C++, Java and other languages, the tool support has been pretty good.  Lack of such professional tools makes it harder for debugging, troubleshooting issues.

Exposure of logic: Since JavaScript is all client side scripting, browsers will just showoff your code and expose your logic, unless you obfuscate it.

Availability of talent: Finding developers, integrators, maintainers, support persons who have exposure to blend of these technologies with-in your budget is really hard.

Managing and presenting data using HTML: Imagine business intelligence reporting applications which has to display tons of data, provide you interactivity to change criteria on reporting to get the right information to help you make a decision with lots of client side scripting is a tremendous task and comes with risks.

Few advantages of Adobe Flex:

Quick Prototyping: Without the pain of a complex content management, one can quickly build applications for a demo and get the audiences captivated.

Desktop or Web: Building the same application for desktop and web is an awesome power to target broad spectrum of users.

Learning curve: Seamless integration with existing Java code; Familiar Eclipse environment.  Having worked with HTML and JavaScript, one should be able to grasp MXML/.AS extremely fast.

Security: Flex provides intense server-side security; protection from cross-domain and zone access; flash security on client side.

Agile: Easily change design, prototype and the processes.

Development and runtime worries: FlexBuilder SDK removes browser and platform worries (unlike with HTML/JavaScript/AJAX) and since Adobe Flash is available on different platforms deployability and testability should be easy.

With all these, seeking a tool like Delphi, Power Builder, or Visual Basic has presumably ended for developing web applications.  There is competing ones like Flex/AIR, Java/JavaFX, and Microsoft Silverlight and may the best one prevail; and my current vote goes to Adobe Flex.

Check out few enterprise applications trying to push Adobe Flex to its limits:

http://sna-demo.ondemand.com/videos/esn-web.html

https://create.ondemand.com/polestar

Finally have a look at http://www.adobe.com/devnet/flex/articles/ten_misconceptions.html


1 Comment

5 Minutes on Adobe Flex – Resize image to fixed height and width …

Off late writing some code for my project, had to write a piece to resize and fit images to fixed constraints.  The exercise was simple and yielded good results.  Idea was to get images, make them uniform so that it can be used to produce elegant UI experience.

Need: scale up/down images, keep aspect ratio (but of course, if the image is too small to fit, then there will be distortion; presume that it is acceptable).

The constraints are predefined somewhere, say the user wants all the images to be of some fixed width and height.

Algorithim:

Search for images (from yahoo or google) using API

Cache images

Resize and Save them

Let me now talk about resize for instance, the function resizeBitmap will transform the original image so be cautious if you want to modify a clone.

public function resizeBitmap(bitmap:Bitmap, maxWidth:Number, maxHeight:Number):void
{
	var bitmapData:BitmapData = bitmap.bitmapData;
	var scaleFactor:Number = 1;
	
	var newWidth:Number = maxWidth;
	var newHeight:Number = maxHeight;
	
	if(bitmapData.width &gt; bitmapData.height) 
	{
		scaleFactor = maxWidth / bitmapData.width;
	}
	else 
	{
		scaleFactor = maxHeight / bitmapData.height;
	}

	newWidth = bitmapData.width * scaleFactor;
	newHeight = bitmapData.height * scaleFactor;
	
	var scaledBitmapData:BitmapData = new BitmapData(newWidth, newHeight);
	var scaleMatrix:Matrix = new Matrix();
	scaleMatrix.scale(scaleFactor, scaleFactor);
	
	scaledBitmapData.draw(bitmap, scaleMatrix);
	bitmap.bitmapData = scaledBitmapData;
}


Leave a comment

5 Minutes on Java – A dictionary based XSS detection …

Cross-Site-Scripting detection is a very fundamental thing to do for web developers.  Often, this is one of prime security concerns.  There are many ways one can implement them, depending on where XSS must be detected.

Let me bring the context of servlets and XSS validation.  The simplest way is to validate all the parameters before processing them.  This way, SQL injection using XSS can be caught, or even running some kind of code can be forbidden which can be useful incases where forwards are done.

This XssValidator class should do the job, since its dictionary based, dictionary can be updated to beef-up protection against vulnerabilities as and when new ones are found.

package udy.foss.utils;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.log4j.Logger;

public class XssValidator {
	private static final Logger logger = Logger.getLogger(XssValidator.class.getName());
	private static ArrayList dictionary = new ArrayList();

	public static void loadDictionary(FileInputStream fis){
		try{
			DataInputStream in = new DataInputStream(fis);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;

			// Read each vulnerability
			while((strLine = br.readLine()) != null) {
				// Add only non-empty lines
				if(strLine.trim().length() &amp;gt; 0) {
					// Add the line to dictionary only if the rule is not in dictionary
					if(dictionary.contains(strLine) == false) {
						dictionary.add(strLine);
					}
				}
			}

			in.close();
		}catch (Exception e){
			logger.debug(&quot;Exception loading dictionaryt&quot; + e.getMessage());
		}
	}

	public static boolean isSafe(String string){
		if(string == null || string.length() &amp;lt;= 0) return true;

		for(int idx = 0; idx &amp;lt; dictionary.size(); idx++){
			String rule = (dictionary.get(idx).trim().toLowerCase());
			if(string.trim().toLowerCase().contains(rule)){
				return false;
			}
		}
		return true;
	}
}

Consider a servlet which initializes and loads the dictionary using the below method.

synchronized public static void initialize(ServletConfig config) throws ServletException {
		try {
			XssValidator.loadDictionary(new FileInputStream(config.getServletContext().getRealPath(&quot;WEB-INF/XSS.dict&quot;)));
		}catch(Exception e){
			logger.debug(&quot;Exception loading XSS dictionary&quot;);
		}
	}

Once the dictionary is loaded, the parameters can be validated using the Validator method.

String someParam = request.getParameter(&quot;someParam&quot;);
	if(XssValidator.isSafe(someParam)){
		// Take some action here
	}

The content of the XSS.dict is enclosed below.

%3c
&amp;amp;gt
&amp;gt;
&amp;amp;lt
&amp;lt;
:expr
:url
?import
@import
@import
cdata[
[cdata
&lt;?xml
alert
background =
background=
background-image
behavior:
bgsound
classid =
classid=
cmd =
cmd=
content =
content=
data:
datasrc =
datasrc=
dynsrc =
dynsrc=
expression
href =
href=
http:
http-equiv =
http-equiv=
id=
image/svg+xml
implementation =
implementation=
javascript
javascript:
layer
list-style-image
livescript
livescript:
lowsrc =
lowsrc=
namespace
onload
rel =
rel=
script
src =
src=
style=
stylesheet
text/css
text/html
text/javascript
text/x-scriptlet
type =
type=
url =
url=
vbscript
vbscript:
xss