# ZipBrowser Example

The following example illustrates the use of the `Request`, `Response`, and `Query` objects. The example uses the `java.util.zip` package to implement a Java CFX called `ZipBrowser,` which is a zip file browsing tag.

The fully qualified path of the zip archive to browse is specified using the `ARCHIVE` attribute. The name of the query to return to the calling page is specified using the `NAME` attribute. The query returned contains three columns: Name, Size, and Compressed.

For example, to query an archive at the path `c:\logfiles.zip` for its contents and to output the results you would use the following CFML code:

    <CFX_ZipBrowser
          ARCHIVE="c:\logfiles.zip"
          NAME="LogFiles" >

    <CFOUTPUT QUERY="LogFiles">
    #Name#,  #Size#, #Compressed# <BR>
    </CFOUTPUT>

The Java implementation of `ZipBrowser` is as follows:

    import com.allaire.cfx.* ;
    import java.util.Hashtable ;
    import java.io.FileInputStream ;
    import java.util.zip.* ;

    public class ZipBrowser implements CustomTag
    {
       public void processRequest( Request request, Response response )
          throws Exception
       {
          // validate that required attributes were passed
          if (  !request.attributeExists( "ARCHIVE" ) ||
                !request.attributeExists( "NAME" ) )
          {
             throw new Exception(
                "Missing attribute (ARCHIVE and NAME are both " +
                "required attributes for this tag)" ) ;
          }
         // get attribute values
          String strArchive = request.getAttribute( "ARCHIVE" ) ;
          String strName = request.getAttribute( "NAME" ) ;

        // create a query to use for returning the list of files
          String[] columns = { "Name", "Size", "Compressed" } ;
          int iName = 1, iSize = 2, iCompressed = 3 ;
          Query files = response.addQuery( strName, columns ) ;

        // read the zip file and build a query from its contents
          ZipInputStream zin =
             new ZipInputStream( new FileInputStream(strArchive) ) ;
          ZipEntry entry ;
          while ( ( entry = zin.getNextEntry()) != null )
          {
             // add a row to the results
             int iRow = files.addRow() ;

             // populate the row with data
             files.setData( iRow, iName,
                entry.getName() ) ;
             files.setData( iRow, iSize,
                String.valueOf(entry.getSize()) ) ;
             files.setData( iRow, iCompressed,
                String.valueOf(entry.getCompressedSize()) ) ;

             // finish up with entry
             zin.closeEntry() ;
          }

          // close the archive
          zin.close() ;
       }
    }