/* * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at . * * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT * WARRANTY OF ANY KIND, either express or implied. See the License for the specific * language governing rights and limitations under the License. * * The Original Code is the Venice Web Communities System. * * The Initial Developer of the Original Code is Eric J. Bowersox , * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * * Contributor(s): */ package com.silverwrist.dynamo.util; import java.io.*; import org.apache.log4j.Logger; import com.silverwrist.dynamo.HttpStatusCode; import com.silverwrist.dynamo.except.*; import com.silverwrist.dynamo.iface.*; public class BufferTextRenderControl extends BaseDelegatingServiceProvider implements TextRenderControl { /*-------------------------------------------------------------------------------- * Internal class which is used to render subobjects *-------------------------------------------------------------------------------- */ private class SubTextRenderControl implements TextRenderControl { /*==================================================================== * Constructor *==================================================================== */ SubTextRenderControl() { // do nothing } // end constructor /*==================================================================== * Implementations from interface ServiceProvider *==================================================================== */ /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass) { return BufferTextRenderControl.this.queryService(klass); } // end queryService /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @param serviceid ID for the service to be requested, to further discriminate between requests. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass, String serviceid) { return BufferTextRenderControl.this.queryService(klass,serviceid); } // end queryService /*==================================================================== * Implementations from interface RenderControl *==================================================================== */ public void setContentType(String type) throws RenderingException { BufferTextRenderControl.this.setContentType(type); } // end setContentType public void setContentLength(int length) throws RenderingException { BufferTextRenderControl.this.setContentLength(length); } // end setContentLength /*==================================================================== * Implementations from interface TextRenderControl *==================================================================== */ public PrintWriter getWriter() throws IOException, RenderingException { return BufferTextRenderControl.this.getWriter(); } // end getWriter public void renderSubObject(Object obj) throws IOException, RenderingException { BufferTextRenderControl.this.renderSubObject(obj); } // end renderSubObject } // end class SubTextRenderControl /*-------------------------------------------------------------------------------- * Internal class which is used to render subobjects *-------------------------------------------------------------------------------- */ private class SubSelfRenderControl implements SelfRenderControl { /*==================================================================== * Constructor *==================================================================== */ SubSelfRenderControl() { // do nothing } // end constructor /*==================================================================== * Implementations from interface ServiceProvider *==================================================================== */ /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass) { return BufferTextRenderControl.this.queryService(klass); } // end queryService /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @param serviceid ID for the service to be requested, to further discriminate between requests. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass, String serviceid) { return BufferTextRenderControl.this.queryService(klass,serviceid); } // end queryService /*==================================================================== * Implementations from interface SelfRenderControl *==================================================================== */ public void status(HttpStatusCode code) throws RenderingException { throw new RenderingException(BufferTextRenderControl.class,"UtilityMessages","selfRender.noStatus"); } // end statis public void redirect(String location) throws IOException, RenderingException { throw new RenderingException(BufferTextRenderControl.class,"UtilityMessages","selfRender.noRedirect"); } // end redirect public void error(HttpStatusCode code) throws IOException, RenderingException { throw new RenderingException(BufferTextRenderControl.class,"UtilityMessages","selfRender.noSetErr"); } // end error public void error(HttpStatusCode code, String message) throws IOException, RenderingException { throw new RenderingException(BufferTextRenderControl.class,"UtilityMessages","selfRender.noSetErr"); } // end error public TextRenderControl getTextRender() throws RenderingException { return new SubTextRenderControl(); } // end getTextRender public BinaryRenderControl getBinaryRender() throws RenderingException { throw new RenderingException(BufferTextRenderControl.class,"UtilityMessages","binaryInsideText"); } // end getBinaryRender } // end class SubSelfRenderControl /*-------------------------------------------------------------------------------- * Internal class which counts the characters it's fed *-------------------------------------------------------------------------------- */ private class BufferWriter extends FilterWriter { /*==================================================================== * Attributes *==================================================================== */ private int m_charcount = 0; /*==================================================================== * Constructor *==================================================================== */ BufferWriter(Writer wr) { super(wr); } // end constructor /*==================================================================== * Overrides from class FilterWriter *==================================================================== */ public void write(int c) throws IOException { if ((m_length>=0) && (m_charcount==m_length)) throw new IOException("Exceeded set output length"); super.write(c); m_charcount++; } // end write public void write(char[] cbuf, int off, int len) throws IOException { if ((m_length>=0) && ((m_charcount + len)>m_length)) throw new IOException("Exceeded set output length"); super.write(cbuf,off,len); m_charcount += len; } // end write public void write(String str, int off, int len) throws IOException { if ((m_length>=0) && ((m_charcount + len)>m_length)) throw new IOException("Exceeded set output length"); super.write(str,off,len); m_charcount += len; } // end write } // end class BufferWriter /*-------------------------------------------------------------------------------- * Static data members *-------------------------------------------------------------------------------- */ private static Logger logger = Logger.getLogger(BufferTextRenderControl.class); /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- */ private StringWriter m_data; private PrintWriter m_wr = null; private String m_type = null; private int m_length = -1; /*-------------------------------------------------------------------------------- * Constructor *-------------------------------------------------------------------------------- */ public BufferTextRenderControl(ServiceProvider services) { super("BufferTextRenderControl",services); m_data = new StringWriter(); } // end constructor /*-------------------------------------------------------------------------------- * Implementations from interface RenderControl *-------------------------------------------------------------------------------- */ public synchronized void setContentType(String type) throws RenderingException { if (m_type==null) m_type = type; } // end setContentType public synchronized void setContentLength(int length) throws RenderingException { if (m_length<0) m_length = length; } // end setContentLength /*-------------------------------------------------------------------------------- * Implementations from interface TextRenderControl *-------------------------------------------------------------------------------- */ public synchronized PrintWriter getWriter() throws IOException, RenderingException { if (m_wr==null) m_wr = new PrintWriter(new BufferWriter(m_data)); return m_wr; } // end getWriter public void renderSubObject(Object obj) throws IOException, RenderingException { if (obj instanceof SelfRenderable) { // this object can render itself - let's do that! SubSelfRenderControl control = new SubSelfRenderControl(); ((SelfRenderable)obj).render(control); return; } // end if QueryRenderer qrend = (QueryRenderer)(super.queryService(QueryRenderer.class)); Renderer rend = qrend.getRendererForObject(obj); if (rend==null) { // the only thing we know about this is that we can get its string equivalent, // so send that out PrintWriter wr = this.getWriter(); wr.println(obj.toString()); return; } // end if if (rend instanceof TextRenderer) { // render subobject here SubTextRenderControl control = new SubTextRenderControl(); ((TextRenderer)rend).render(obj,control); } // end if else if (rend instanceof BinaryRenderer) // cannot render binary objects as a subobject to text objects! throw new RenderingException(BufferTextRenderControl.class,"UtilityMessages","binaryInsideText"); else { // default to raw text logger.error("Unknown renderer object class: " + rend.getClass().getName()); PrintWriter wr = this.getWriter(); wr.println(obj.toString()); } // end else } // end renderSubObject /*-------------------------------------------------------------------------------- * External operations *-------------------------------------------------------------------------------- */ public String getContentType() { return m_type; } // end getContentType public int getDataLength() { return m_data.getBuffer().length(); } // end getDataLength public String getData() { return m_data.toString(); } // end getData } // end class BufferTextRenderControl