Per a corregir-ho, enlloc d'entrar a tots els articles i modificar-ne el tipus de lletra (amb el risc d'oblidar-ne algun), el que hem fet ha estat crear un filtre que modifiqui la sortida cap al navegador substituïnt el tipus de lletra per "Arial".
S'ha pogut fer mitjançant tres classes:
- FiltreCanviarFontDeHelveticaAArial, el filtre encarregat del processament
- HttpServletResponseAmbBuffer, un wrapper de la resposta que permet actuar sobre un buffer enlloc de l'stream de sortida.
- ServletOutputStreamCopier, l'stream usat com a buffer
A continuació hi ha el codi de les tres classes:
FiltreCanviarFontDeHelveticaAArial.java
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
/**
*
* @author Oscar Pérez del Campo
*/
public class FiltreCanviarFontDeHelveticaAArial implements Filter
{
private static final boolean debug = true;
// The filter configuration object we are associated with. If
// this value is null, this filter instance is not currently
// configured.
private FilterConfig filterConfig = null;
public FiltreCanviarFontDeHelveticaAArial()
{
}
private void doBeforeProcessing(ServletRequest request, ServletResponse response)
throws IOException, ServletException
{
if (debug)
{
log("FiltreCanviarFontDeHelveticaAArial:DoBeforeProcessing");
}
}
private void doAfterProcessing(ServletRequest request, HttpServletResponseAmbBuffer response)
throws IOException, ServletException
{
if (debug)
{
log("FiltreCanviarFontDeHelveticaAArial:DoAfterProcessing");
}
byte[] dades = response.getCopy();
String strResposta = new String(dades);
if (!StringUtils.isEmpty(strResposta))
{
strResposta = strResposta.replaceAll("font-family:[ ]*helvetica", "font-family: arial");
response.substitueixResposta(strResposta);
}
}
/**
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @param chain The filter chain we are processing
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet error occurs
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
if (debug)
{
log("FiltreCanviarFontDeHelveticaAArial:doFilter()");
}
OutputStream osOriginal = response.getOutputStream();
HttpServletResponseAmbBuffer resp = new HttpServletResponseAmbBuffer((HttpServletResponse)response);
doBeforeProcessing(request, resp);
Throwable problem = null;
try
{
chain.doFilter(request, resp);
} catch (Throwable t)
{
// If an exception is thrown somewhere down the filter chain,
// we still want to execute our after processing, and then
// rethrow the problem after that.
problem = t;
t.printStackTrace();
}
doAfterProcessing(request, resp);
osOriginal.write(resp.getCopy());
// If there was a problem, we want to rethrow it if it is
// a known type, otherwise log it.
if (problem != null)
{
if (problem instanceof ServletException)
{
throw (ServletException) problem;
}
if (problem instanceof IOException)
{
throw (IOException) problem;
}
sendProcessingError(problem, resp);
}
}
/**
* Return the filter configuration object for this filter.
*/
public FilterConfig getFilterConfig()
{
return (this.filterConfig);
}
/**
* Set the filter configuration object for this filter.
*
* @param filterConfig The filter configuration object
*/
public void setFilterConfig(FilterConfig filterConfig)
{
this.filterConfig = filterConfig;
}
/**
* Destroy method for this filter
*/
public void destroy()
{
}
/**
* Init method for this filter
*/
public void init(FilterConfig filterConfig)
{
this.filterConfig = filterConfig;
if (filterConfig != null)
{
if (debug)
{
log("FiltreCanviarFontDeHelveticaAArial:Initializing filter");
}
}
}
/**
* Return a String representation of this object.
*/
@Override
public String toString()
{
if (filterConfig == null)
{
return ("FiltreCanviarFontDeHelveticaAArial()");
}
StringBuffer sb = new StringBuffer("FiltreCanviarFontDeHelveticaAArial(");
sb.append(filterConfig);
sb.append(")");
return (sb.toString());
}
private void sendProcessingError(Throwable t, ServletResponse response)
{
String stackTrace = getStackTrace(t);
if (stackTrace != null && !stackTrace.equals(""))
{
try
{
response.setContentType("text/html");
PrintStream ps = new PrintStream(response.getOutputStream());
PrintWriter pw = new PrintWriter(ps);
pw.print("\n\nError \n\n\n"); //NOI18N
// PENDING! Localize this for next official release
pw.print("
The resource did not process correctly
\n\n");
pw.print(stackTrace);
pw.print("
\n"); //NOI18N
pw.close();
ps.close();
response.getOutputStream().close();
} catch (Exception ex)
{
}
} else
{
try
{
PrintStream ps = new PrintStream(response.getOutputStream());
t.printStackTrace(ps);
ps.close();
response.getOutputStream().close();
} catch (Exception ex)
{
}
}
}
public static String getStackTrace(Throwable t)
{
String stackTrace = null;
try
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
sw.close();
stackTrace = sw.getBuffer().toString();
} catch (Exception ex)
{
}
return stackTrace;
}
public void log(String msg)
{
filterConfig.getServletContext().log(msg);
}
}
HttpServletResponseAmbBuffer.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
*
* @author Oscar Pérez del Campo
*/
public class HttpServletResponseAmbBuffer extends HttpServletResponseWrapper
{
private ServletOutputStream outputStream;
private PrintWriter writer;
private ServletOutputStreamCopier copier;
public HttpServletResponseAmbBuffer(HttpServletResponse response) throws IOException
{
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException
{
if (writer != null)
{
throw new IllegalStateException("getWriter() has already been called on this response.");
}
if (outputStream == null)
{
outputStream = getResponse().getOutputStream();
copier = new ServletOutputStreamCopier(outputStream);
}
return copier;
}
@Override
public PrintWriter getWriter() throws IOException
{
if (writer == null)
{
writer = new PrintWriter(new OutputStreamWriter(this.getOutputStream(), getResponse().getCharacterEncoding()), true);
}
return writer;
}
@Override
public void flushBuffer() throws IOException
{
if (writer != null)
{
writer.flush();
} else if (outputStream != null)
{
copier.flush();
}
}
public byte[] getCopy()
{
if (copier != null)
{
return copier.getCopy();
} else
{
return new byte[0];
}
}
public void substitueixResposta(String str) throws IOException
{
copier.substitueixContinguts(str);
}
}
ServletOutputStreamCopier.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletOutputStream;
/**
*
* @author Oscar Pérez del Campo
*/
public class ServletOutputStreamCopier extends ServletOutputStream
{
private OutputStream outputStream;
public ServletOutputStreamCopier(OutputStream outputStream)
{
this.outputStream = new ByteArrayOutputStream(2048);
}
@Override
public void write(int b) throws IOException
{
outputStream.write(b);
}
public byte[] getCopy()
{
return ((ByteArrayOutputStream) outputStream).toByteArray();
}
void substitueixContinguts(String str) throws IOException
{
if (outputStream != null)
{
outputStream.close();
}
outputStream = new ByteArrayOutputStream();
outputStream.write(str.getBytes());
}
}