/******************************************************************************
* JBoss, a division of Red Hat *
* Copyright 2006, Red Hat Middleware, LLC, and individual *
* contributors as indicated by the @authors tag. See the *
* copyright.txt in the distribution for a full listing of *
* individual contributors. *
* *
* This is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation; either version 2.1 of *
* the License, or (at your option) any later version. *
* *
* This software is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this software; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
******************************************************************************/
package org.jboss.portletbridge.richfaces.resource;
import org.ajax4jsf.resource.CompressedScriptRenderer;
import org.ajax4jsf.resource.InternetResource;
import org.ajax4jsf.resource.ResourceContext;
import org.ajax4jsf.Messages;
import org.ajax4jsf.javascript.JSMin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* @author <a href="mailto:whales@redhat.com">Wesley Hales</a>
* @version $Revision: 630 $
*/
public class PortletScriptRenderer extends CompressedScriptRenderer {
private static final String COMPRESS_SCRIPTS_PARAMETER = "org.ajax4jsf.COMPRESS_SCRIPT";
private static final Log _log = LogFactory.getLog(PortletScriptRenderer.class);
public int send(InternetResource base, ResourceContext context) throws IOException {
InputStream in = base.getResourceAsStream(context);
if (null == in) {
String message = Messages.getMessage(
Messages.NO_INPUT_STREAM_ERROR, base.getKey());
throw new IOException(message);
}
String scriptId = context.getPathInfo();
OutputStream out = context.getOutputStream();
scriptId = scriptId.substring(scriptId.lastIndexOf("/") + 1);
scriptId = "RF_" + scriptId.replace(".","_");
scriptId = scriptId.replace("-","_");
convert(out,in,scriptId);
// Compress JavaScript output by JSMin ( true by default )
if (!"false".equalsIgnoreCase(context.getInitParameter(COMPRESS_SCRIPTS_PARAMETER))) {
CountingOutputStream countingStream = new CountingOutputStream(out);
JSMin jsmin = new JSMin(in, countingStream);
try {
jsmin.jsmin();
} catch (Exception e) {
_log.error("Error send script to client for resource " + base.getKey(), e);
} finally {
in.close();
countingStream.flush();
countingStream.close();
}
int written = countingStream.getWritten();
if (_log.isDebugEnabled()) {
_log.debug("Send " + written + " bytes to client for JavaScript resource " + base.getKey());
}
return written;
} else {
return sendStream(in, out);
}
}
public boolean convert(java.io.OutputStream out, java.io.InputStream in, String scriptId) throws IOException {
try {
int r;
int s;
int e;
InputStream preScript = new IOStringInputStream("if(!window." + scriptId + "){\nwindow." + scriptId + " = {};\n");
InputStream postScript = new IOStringInputStream("\n}\n");
while ((r = in.read()) != -1) {
while ((s = preScript.read()) != -1) {
out.write(s);
}
out.write(r);
}
while ((e = postScript.read()) != -1) {
out.write(e);
}
return true;
} catch (java.io.IOException ioe) {
return false;
}
}
}
class CountingOutputStream extends OutputStream {
private OutputStream outputStream;
private int written = 0;
CountingOutputStream(OutputStream outputStream) {
super();
this.outputStream = outputStream;
}
public void close() throws IOException {
outputStream.close();
}
public void flush() throws IOException {
outputStream.flush();
}
public void write(byte[] b, int off, int len) throws IOException {
outputStream.write(b, off, len);
written += len;
}
public void write(byte[] b) throws IOException {
outputStream.write(b);
written += b.length;
}
public void write(int b) throws IOException {
outputStream.write(b);
written++;
}
int getWritten() {
return written;
}
}
class IOStringInputStream extends java.io.InputStream {
private StringBuffer buffer;
public IOStringInputStream(String text) {
buffer = new StringBuffer(text);
}
private int position = 0;
public int read() throws java.io.IOException {
if (position < buffer.length()) {
return buffer.charAt(position++);
} else {
return -1;
}
}
}