dev@jsftemplating.java.net

Re: JSFTemplating: FileStreamer Patch

From: Ken Paulsen <Ken.Paulsen_at_Sun.COM>
Date: Sun, 16 Mar 2008 11:49:44 -0700

Hi Jason,

This looks great!

It would be great if eventually we could move the code you wrote to find files via a JAR to a util method to use in other areas.

As for not working in other classpath jars... I'm not too concerned, people can modify their web.xml if they want to go this route for now.  If we need to support that use case, we can figure out a solution (additional search paths, or a flag to use the slower getResources() method, for example).  I plan to do a performance test on this code vs. getResources to see just how much time we saved (if any).  ;)  I hope to see that it significantly helps -- I think it will show that.

Go ahead and commit the changes.

Thanks!

Ken

Jason Lee wrote:
Below is a diff of the changes I've just made to FileStreamer.java.
In a nut shell, when a FileStreamer is being constructed, it will find
all the JAR files in the web app and query each jar for
META-INF/jsftemplating/fileStreamer.properties.  If it is found, it
will load the file into a Properties, and fetch the contentSources
property, which is a comma-delimited list of ContentSources to be
registered.  This mechanism should allow for ContentSource
registration without the need for external configuration, such as is
currently needed for the FileStreamer Servlet, for example.  This is
not complete yet, as we need to look in META-INF of the web app
itself, in case an app author has included a CS in his app, but not in
a jar.  I'm also pretty certain that any such JAR files deployed to
the application server lib directory will be missed.  Not sure how to
handle that in a performant manner, but this is at least a start.
I'll commit this as soon as we're all happy with it.  Note that it
looks like NetBeans did a trick with some of Ken's formatting, so this
is bigger than it really is.  If we'd all just use spaces... :P

Bed time! :)

Index: src/java/com/sun/jsftemplating/util/fileStreamer/FileStreamer.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/util/fileStreamer/FileStreamer.java,v
retrieving revision 1.5
diff -r1.5 FileStreamer.java
34c34,42
<
---
  
import java.io.File;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
    
47a56
  
    public static final String CONTENT_SOURCES = "contentSources";
    
53c62,83
< 	super();
---
  
        super();
        try {
            ServletContext sc = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
            @SuppressWarnings("unchecked")
            Set<String> paths = (Set<String>) sc.getResourcePaths("/WEB-INF/lib/");
            for (String path : paths) {
                if ("jar".equalsIgnoreCase(path.substring(path.length() - 3))) {
                    JarFile jarFile = new JarFile(new File(sc.getResource(path).getFile()));
                    ZipEntry jarEntry = jarFile.getEntry("META-INF/jsftemplating/fileStreamer.properties");
                    if (jarEntry != null) {
                        Properties props = new Properties();
                        InputStream is = jarFile.getInputStream(jarEntry);
                        props.load(is);
                        is.close();
                        jarFile.close();
                        processFileStreamerProperties(props);
                    }
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(FileStreamer.class.getName()).log(Level.SEVERE, null, ex);
        }
    
142,143c172,184
< 	// Clean Up
< 	source.cleanUp(ctx);
---
  
        // Clean Up
        source.cleanUp(ctx);
    }


    protected void processFileStreamerProperties(Properties props) {
        String contentSourcesProp = (String)props.get(CONTENT_SOURCES);
        if ((contentSourcesProp != null) && (contentSourcesProp.length() > 0)) {
            String[] contentSources = contentSourcesProp.split(",");
            for (String cs : contentSources) {
                this.registerContentSource(cs);
            }
        }
    
145a187
  
154,155c196,197
< 	// Get the InputStream
< 	InputStream in = source.getInputStream(context);
---
  
        // Get the InputStream
        InputStream in = source.getInputStream(context);
    
157,158c199,200
< 	// Get the OutputStream
< 	if (in == null) {
---
  
        // Get the OutputStream
        if (in == null) {
    
160c202
< 	    throw new FileNotFoundException();
---
  
            throw new FileNotFoundException();
    
164,165c206,207
< 		    //Mainly to take care of javahelp2, bcz javahelp2 code needs
an Exception to be thrown for FileNotFound.
< 		    //We may have to localize this message.
---
  
        //Mainly to take care of javahelp2, bcz javahelp2 code needs an Exception to be thrown for FileNotFound.
        //We may have to localize this message.
    
168c210
< 		    //squelch it, just return.
---
  
        //squelch it, just return.
    
172c214
< 	    // nothing to write, already done
---
  
        // nothing to write, already done
    
174c216
< 	}
---
  
        }
    
176c218
< 	OutputStream out = context.getOutputStream();
---
  
        OutputStream out = context.getOutputStream();
    
178,179c220,221
< 	// Get the InputStream
< 	InputStream stream = new BufferedInputStream(in);
---
  
        // Get the InputStream
        InputStream stream = new BufferedInputStream(in);
    
181,182c223,224
< 	// Write the header
< 	context.writeHeader(source);
---
  
        // Write the header
        context.writeHeader(source);
    
184,189c226,227
< 	// Copy the data to the ServletOutputStream
< 	byte [] buf = new byte[512]; // Set our buffer at 512 bytes
< 	int read = stream.read(buf, 0, 512);
< 	while (read != -1) {
< 	    // Write data from the OutputStream to the InputStream
< 	    out.write(buf, 0, read);
---
  
        // Copy the data to the ServletOutputStream
        byte[] buf = new byte[512]; // Set our buffer at 512 bytes
    
191,193c229,236
< 	    // Read more...
< 	    read = stream.read(buf, 0, 512);
< 	}
---
  
        int read = stream.read(buf, 0, 512);
        while (read != -1) {
            // Write data from the OutputStream to the InputStream
            out.write(buf, 0, read);

            // Read more...
            read = stream.read(buf, 0, 512);
        }
    
195,196c238,239
< 	// Close the Stream
< 	stream.close();
---
  
        // Close the Stream
        stream.close();
    
349,352c392,394
< 	    "application/octet-stream";
<
<     private static FileStreamer    _streamer	= new FileStreamer();
< }
---
  
            "application/octet-stream";
    private static FileStreamer _streamer = new FileStreamer();
}
    
\ No newline at end of file