jueves, 28 de mayo de 2009

ICEfaces 1.8.0 + <ice:outputResource/> (english version)

Hi

I’m going to try to explain how to show a list of file from a folder so you can download using the new <ice:outputResource/> of ICEfaces 1.8.0

In the component-showcase example you can download just one file, and I wanted to show a list of files from a folder and download it all. After thinking on it a lot and with the help of lmaciass from the ICEfaces forum I devoloped a working example, and I’m going to try to explain.

Step 1:

Create a class with the information of the file and the resoruce to create, Resource (import com.icesoft.faces.context.Resource;):

public class ResourceBean {

Resource resource;
String fileName;
String fileDescription;
/**
* @param resource
* @param fileName
* @param fileDescription
*/
public ResourceBean(Resource resource, String fileName,
String fileDescription) {

this.resource = resource;
this.fileName = fileName;
this.fileDescription = fileDescription;
}
Añadir los getters/setters que faltan y listo
........
}


Step 2:

Create a class to read from the folder and create a list (to show in datatable) of ResourceBean objects. Each of this object will contain the information to download.


public class RecursoDescarga {

// Lista con cada uno de los recursos
private List resourceBeanList = null;
// Recurso independiente para añadir a la lista de recursos
private ResourceBean resourceBean = null;


public RecursoDescarga() {
init();
}

private void init() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
.getExternalContext().getSession(true);
//UPLOAD_PATH2 es algo así como "upload/";
//Cada uno tendrá que modificarlo donde lo tengo, en mi caso justo bajo el WebContent
String basePathFile = session.getServletContext().getRealPath(
Rutas.UPLOAD_PATH2);

File dir = new File(basePathFile);
List list = getFileListing(dir);

ArrayList items = new ArrayList();
for (int i = 0; i < list.size(); i++) {
String pdfFileName = ((File) list.get(i)).getName();
try {

resourceBean = downloadFile(basePathFile, pdfFileName, "");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
items.add(resourceBean);
}
resourceBeanList = items;

Step 3:

The downloadFile method:

public ResourceBean downloadFile(String path, String fileName,
String fileDescription) throws IOException,
IllegalArgumentException {

if (path == null || path.equals("") || fileName == null
|| fileName.equals("")) {
throw new IllegalArgumentException("Argumento Ilegal");
}
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();

Resource res = new ByteArrayResource(toByteArray(ec
.getResourceAsStream(Rutas.UPLOAD_PATH4 + "/" + fileName)));

return new ResourceBean(res, fileName, fileDescription);

}

public static byte[] toByteArray(InputStream input) throws IOException {

ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int len = 0;
while ((len = input.read(buf)) > -1)
output.write(buf, 0, len);
return output.toByteArray();
}

Step 4:

Finally the two method to read the files from the folder:

public List getFileListing(File dir) {
List list = getFileListingNoSort(dir);
Collections.sort(list);

return list;

}

private List getFileListingNoSort(File dir) {
List list = new ArrayList();
File[] filesAndDirs = dir.listFiles();
List filesDirs = Arrays.asList(filesAndDirs);

for (File file : filesDirs) {
if (file.isFile()) {
list.add(file);
}
}

return list;
}


Step 5:

jspx page

<dataTable id="downloadFiles"
value="#{recursoDescarga.resourceBeanList}" var="resources">
<ice:column>
<f::facet name="header">
<ice:outputText style="text-align:left;"
value="#{msgs['nombre.de.archivo']}" />
</f::facet>
<ice:outputText value="#{resources.fileName}" />
</ice:column>
<ice:column style="text-align:center;">
<f::facet name="header">
<ice:outputText value="#{msgs['descargar']}" />
</f::facet>

<ice:outputResource label="#{msgs['descargar']}"
resource="#{resources.resource}"
image="./xmlhttp/images/LogoPDF.gif" mimeType="application/pdf"
fileName="#{resources.fileName}" attachment="true"
shared="false" style="width:150px" />
</ice:column>

<ice:column>
< f::facet name="header">
<ice:outputText value="#{msgs['descripcion']}" />
</f::facet>
<ice:outputText value="#{resources.fileDescription }" />
</ice:column>
</ice:dataTable>


Step 6:

Declare RecursoDescarga in faces-config-bean.xml


I hope it Works

Thanks

miércoles, 27 de mayo de 2009

ICEfaces 1.8.0 + <ice:outputResource/>

Hola.

Voy a intentar explicar como mostrar una lista de ficheros para descargar utilizando el nuevo <ice:outputResource/> de ICEfaces 1.8.0

En el ejemplo que aparece en el component-showcase sólo permite descargar un fichero y yo lo que quería era poder mostrar una lista de ficheros ubicados en un directorio particular con la opción de descargar cualquiera de ellos. Después de devanarme los sesos y con la ayuda de lmaciass en el foro de icefaces he conseguido que funcione y voy a intentar explicar como.

Paso 1:

Crear una clase que contenga la información de cada uno de los ficheros, así como el elemento Resource (import com.icesoft.faces.context.Resource;) tal que así:

public class ResourceBean {

Resource resource;
String fileName;
String fileDescription;
/**
* @param resource
* @param fileName
* @param fileDescription
*/
public ResourceBean(Resource resource, String fileName,
String fileDescription) {

this.resource = resource;
this.fileName = fileName;
this.fileDescription = fileDescription;
}
Añadir los getters/setters que faltan y listo
........
}


Paso 2:

Crear una clase que se encarge de leer desde la carpeta donde tengo los ficheros y crear una lista (para mostrar con el datatable) de objetos tipo ResourceBean. Cada uno de ellos contendrá la información para cada fichero a descargar.

public class RecursoDescarga {

// Lista con cada uno de los recursos
private List resourceBeanList = null;
// Recurso independiente para añadir a la lista de recursos
private ResourceBean resourceBean = null;


public RecursoDescarga() {
init();
}

private void init() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
.getExternalContext().getSession(true);
//UPLOAD_PATH2 es algo así como "upload/";
//Cada uno tendrá que modificarlo donde lo tengo, en mi caso justo bajo el WebContent
String basePathFile = session.getServletContext().getRealPath(
Rutas.UPLOAD_PATH2);

File dir = new File(basePathFile);
List list = getFileListing(dir);

// ArrayList items = new ArrayList();
ArrayList items = new ArrayList();
for (int i = 0; i < list.size(); i++) {
String pdfFileName = ((File) list.get(i)).getName();
try {

resourceBean = downloadFile(basePathFile, pdfFileName, "");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
items.add(resourceBean);
}
resourceBeanList = items;

Paso 3:

A continuación el método downloadFile:

public ResourceBean downloadFile(String path, String fileName,
String fileDescription) throws IOException,
IllegalArgumentException {

if (path == null || path.equals("") || fileName == null
|| fileName.equals("")) {
throw new IllegalArgumentException("Argumento Ilegal");
}
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();

Resource res = new ByteArrayResource(toByteArray(ec
.getResourceAsStream(Rutas.UPLOAD_PATH4 + "/" + fileName)));

return new ResourceBean(res, fileName, fileDescription);

}

public static byte[] toByteArray(InputStream input) throws IOException {

ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int len = 0;
while ((len = input.read(buf)) > -1)
output.write(buf, 0, len);
return output.toByteArray();
}

Paso 4:

Por último os pongo las dos rutinas para obtener los ficheros, que las he encontrado por ahí, y las he utilizado tal cual.


public List getFileListing(File dir) {
List list = getFileListingNoSort(dir);
Collections.sort(list);

return list;

}

private List getFileListingNoSort(File dir) {
List list = new ArrayList();
File[] filesAndDirs = dir.listFiles();
List filesDirs = Arrays.asList(filesAndDirs);

for (File file : filesDirs) {
if (file.isFile()) {
list.add(file);
}
}

return list;
}


Paso 5:

Crear la página .jspx

<dataTable id="downloadFiles"
value="#{recursoDescarga.resourceBeanList}" var="resources">
<ice:column>
<f:facet name="header">
<ice:outputText style="text-align:left;"
value="#{msgs['nombre.de.archivo']}" />
</f:facet>
<ice:outputText value="#{resources.fileName}" />
</ice:column>
<ice:column style="text-align:center;">
<f:facet name="header">
<ice:outputText value="#{msgs['descargar']}" />
</f:facet>

<ice:outputResource label="#{msgs['descargar']}"
resource="#{resources.resource}"
image="./xmlhttp/images/LogoPDF.gif" mimeType="application/pdf"
fileName="#{resources.fileName}" attachment="true"
shared="false" style="width:150px" />
</ice:column>

<ice:column>
< f:facet name="header">
<ice:outputText value="#{msgs['descripcion']}" />
</f:facet>
<ice:outputText value="#{resources.fileDescription }" />
</ice:column>
</ice:dataTable>


Paso 6:

Declarar el objeto en el faces-config-bean.xml


Bueno, espero haber podido aportar mi granito de arena a este asunto.

Perdonad que no he ajustado los textos correctamente.

Cualquier duda, corrección o comentario

Salu2