Friday, May 28, 2010

Uploading Files: ADF InputFile Component

In this post we will look at how the InputFile component can be used to upload files to the app server. Once the handle of a file is available at the app server then that file can processed in any way desirable. It can be stored on a file system or on a database or sent over a web service message.

Create a JSF page and drag a Input File component available in ADF Faces common components pallete, onto the page.

Next create a backing bean (faces context). Import the class: org.apache.myfaces.trinidad.model.UploadedFile; This class object will hold the reference to the file that will be uploaded using this component.

Here is the sample code for this backing bean:

import org.apache.myfaces.trinidad.model.UploadedFile;

public class FileUploader {
UploadedFile myFile;
public FileUploader() {
}
public String uploadFile() {
System.out.println("inside fileUpload method");
return null;
}
public void setMyFile(UploadedFile myFile) {
this.myFile = myFile;
System.out.println("inside set uploaded file method");
System.out.println("filename is : "+file.getFilename());
System.out.println("type is : "+file.getContentType());
System.out.println("filesize is : "+file.getLength());
}
public UploadedFile getMyFile() {
return myFile;
}
}

Set the value property, of the Input File component to point to the public instance variable myFile of the backing bean class created above. This variable will hold the reference to the file being uploaded.

Next add a push botton to the page and point its action to the uploadFile() method above. In this method you can write the code to process the file that has been uploaded.


Tuesday, May 25, 2010

base64 encoding for attachments in a web service

Attachments can be sent over web services through base64 encoding of the binary files and transporting them as string through a SOAP message.

Here is util file in java for encoding and decoding a binary file into base64 string.

package com.peoplesoft.hr.sa;
import java.util.zip.*;
import java.util.Enumeration;
import java.io.*;
import java.util.Stack;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

public class base64Utils {
public base64Utils() {
}

/**
* encodes a file in base64 format
* @param filename name of the file to encode
* @return String the base64 text of the encoded file
*/
public String base64Encode(String filename) {
BASE64Encoder b64e = new BASE64Encoder();
byte[] temparray, filearray;
int bytecount;
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
filename));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
b64e.encode(bis, bos);
bis.close();
return bos.toString();
}
catch (Exception a) {
return null;
}
}

/**
* decodes a file from base64 format
* @param filename name of the file to decode to
* @param filedata the base64 encoded data
* @return String the base64 text of the encoded file
*/

public boolean base64Decode(String filename, String filedata)
{
BASE64Decoder b64d=new BASE64Decoder();
byte [] outputfile;
try {
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(filename));
outputfile=b64d.decodeBuffer(filedata);
bos.write(outputfile);
bos.close();
}
catch (Exception a) {
return false;
}
return true;
}
}

Downloading a File

Downloading a File:

To a button or a Command link you have to add a File Download Action Listener (af:fileDownloadActionListener). This component can be found under the Operations tab in the component pallete.

The page source code will look like:

<af:commandLink text="#{row.bindings.UserFileName.inputValue}"
shortDesc="#{bindings.SadAttachmentsVO1.hints.UserFileName.tooltip}"
id="it2">
<af:fileDownloadActionListener method="#{ConstituentData_BackingBean.handleFilekDownload}"
filename="#{row.bindings.UserFileName.inputValue}"
contentType="#{row.bindings.FileType.inputValue}"/>
</af:commandLink>


The properties to set are:
- ContentType: the MIME type of the file. This can be retrieved from a VO property is it has been stored along with the file
- Filename: name of the file. Again it should be available along with the file.
- Method: A call to a method on the backing bean, that will prepare the output Stream.

Example: In this method the file data is received as byte array by calling an AM service method. It is then passed onto the output stream.

public void handleFileDownload (FacesContext facesContext, OutputStream outputStream){
try {
Object result = executeMethodWithResult("getCachedAttachment");
outputStream.write((byte[])result);
} catch (IOException e) {
System.out.println("Exception "+e);
}
}

Thursday, May 6, 2010

af:iterator component

Below is a scenario where I tried using af:iterator component. This component will enable you to show multiple records in a layout other than a table. It worked ok for most part but was not able to recognise the value set for the Radio Group.

<af:iterator id="i1"
value="#{bindings.SccAdmExtnDataVO1.collectionModel}"
var="row"
rows="#{bindings.SccAdmExtnDataVO1.rangeSize}">
<af:panelFormLayout id="pfl3">
<af:inputText value="#{row.SeqNo}"
label="#{bindings.SeqNo1.hints.label}"
required="#{bindings.SeqNo1.hints.mandatory}"
columns="#{bindings.SeqNo1.hints.displayWidth}"
maximumLength="#{bindings.SeqNo1.hints.precision}"
shortDesc="#{bindings.SeqNo1.hints.tooltip}"
id="it3">
<f:validator binding="#{bindings.SeqNo1.validator}"/>
</af:inputText>
<af:outputText value="#{row.Question}"
id="ot3"/>
<af:selectOneRadio value="#{row.Answer}"
label="#{bindings.Answer.label}"
required="#{bindings.Answer.hints.mandatory}"
shortDesc="#{bindings.Answer.hints.tooltip}"
id="sor3">
<f:selectItems value="#{bindings.Answer.items}" id="si3"/>
</af:selectOneRadio>
</af:panelFormLayout>
</af:iterator>

Monday, May 3, 2010

XMLGregorianCalendar and Date conversions

Converting from oracle.jbo.domain.Date to java.util.Date to GregoriaCalendar to XMLGregorianCalendar

try {
System.out.println("converting date");
oracle.jbo.domain.Date jboDate = (oracle.jbo.domain.Date )myConstRow.getAttribute("BirthDate");
java.sql.Date sqlDate = jboDate.dateValue();
long longDate = sqlDate.getTime();
java.util.Date javaDate = new java.util.Date(longDate);
GregorianCalendar c = new GregorianCalendar();
c.setTime(javaDate);
XMLGregorianCalendar date2;
date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
constData.setBIRTHDATE(date2);
} catch (DatatypeConfigurationException e) {
System.out.println("Error with converting date");
}

Converting from XMLGregorianCalendar to GregoriaCalendar to java.util.Date to oracle.jbo.domain.Date

System.out.println("Birthdate IF");
java.util.Date javaDate = constData.getBIRTHDATE().toGregorianCalendar().getTime();
long longDate = javaDate.getTime();
java.sql.Date sqlDate = new java.sql.Date(longDate);
oracle.jbo.domain.Date jboDate = new oracle.jbo.domain.Date(sqlDate);
myConstRow.setAttribute("BirthDate", jboDate);