All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wicket.Response Maven / Gradle / Ivy

Go to download

Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and unloading of Wicket components and pageSources.

There is a newer version: 5.0.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.net.URLConnection;
import java.sql.SQLException;
import java.util.List;
import java.util.Locale;

import javax.servlet.ServletContext;

import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.util.io.Streams;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.time.Time;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Abstract base class for different implementations of response writing. A subclass must implement
 * write(String) to write a String to the response destination (whether it be a browser, a file, a
 * test harness or some other place). A subclass may optionally implement close(),
 * encodeURL(String), redirect(String), isRedirect() or setContentType(String) as appropriate.
 * 
 * @author Jonathan Locke
 */
public abstract class Response
{
	private static final Logger log = LoggerFactory.getLogger(Response.class);

	/** Default encoding of output stream */
	private String defaultEncoding;

	/**
	 * Closes the response output stream
	 */
	public void close()
	{
	}

	/**
	 * Called when the Response needs to reset itself. Subclasses can empty there buffer or build up
	 * state.
	 */
	public void reset()
	{
	}

	/**
	 * An implementation of this method is only required if a subclass wishes to support sessions
	 * via URL rewriting. This default implementation simply returns the URL String it is passed.
	 * 
	 * @param url
	 *            The URL to encode
	 * @return The encoded url
	 */
	public CharSequence encodeURL(final CharSequence url)
	{
		return url;
	}

	/**
	 * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT.
	 * 
	 * Loops over all the response filters that were set (if any) with the give response returns the
	 * response buffer itself if there where now filters or the response buffer that was
	 * created/returned by the filter(s)
	 * 
	 * @param responseBuffer
	 *            The response buffer to be filtered
	 * @return Returns the filtered string buffer.
	 */
	public final AppendingStringBuffer filter(AppendingStringBuffer responseBuffer)
	{
		List responseFilters = Application.get()
			.getRequestCycleSettings()
			.getResponseFilters();

		if (responseFilters == null)
		{
			return responseBuffer;
		}

		for (int i = 0; i < responseFilters.size(); i++)
		{
			IResponseFilter filter = responseFilters.get(i);
			responseBuffer = filter.filter(responseBuffer);
		}
		return responseBuffer;
	}

	/**
	 * Get the default encoding
	 * 
	 * @return default encoding
	 */
	public String getCharacterEncoding()
	{
		if (defaultEncoding == null)
		{
			return Application.get().getRequestCycleSettings().getResponseRequestEncoding();
		}
		else
		{
			return defaultEncoding;
		}
	}

	/**
	 * @return The output stream for this response
	 */
	public abstract OutputStream getOutputStream();

	/**
	 * Returns true if a redirection has occurred. The default implementation always returns false
	 * since redirect is not implemented by default.
	 * 
	 * @return True if the redirect method has been called, making this response a redirect.
	 */
	public boolean isRedirect()
	{
		return false;
	}

	/**
	 * CLIENTS SHOULD NEVER CALL THIS METHOD FOR DAY TO DAY USE!
	 * 

* A subclass may override this method to implement redirection. Subclasses which have no need * to do redirection may choose not to override this default implementation, which does nothing. * For example, if a subclass wishes to write output to a file or is part of a testing harness, * there may be no meaning to redirection. *

*

* Framework users who want to redirect should use a construction like * RequestCycle.get().setRequestTarget(new RedirectRequestTarget(...)); * or * setResponsePage(new RedirectPage(...)); * *

* * @param url * The URL to redirect to */ public void redirect(final String url) { } /** * Set the default encoding for the output. Note: It is up to the derived class to make use of * the information. Class Response simply stores the value, but does not apply it anywhere * automatically. * * @param encoding */ public void setCharacterEncoding(final String encoding) { defaultEncoding = encoding; } /** * Set the content length on the response, if appropriate in the subclass. This default * implementation does nothing. * * @param length * The length of the content */ public void setContentLength(final long length) { } /** * Set the content type on the response, if appropriate in the subclass. This default * implementation does nothing. * * @param mimeType * The mime type */ public void setContentType(final String mimeType) { } /** * Set the contents last modified time, if appropriate in the subclass. This default * implementation does nothing. * * @param time * The time object */ public void setLastModifiedTime(Time time) { } /** * @param locale * Locale to use for this response */ public void setLocale(final Locale locale) { } /** * Writes the given tag to via the write(String) abstract method. * * @param tag * The tag to write */ public final void write(final ComponentTag tag) { write(tag.toString()); } /** * Writes the given string to the Response subclass output destination. * * @param string * The string to write */ public abstract void write(final CharSequence string); /** * Either throws the exception wrapped as {@link WicketRuntimeException} or silently ignores it. * This method should ignore IO related exceptions like connection reset by peer or broken pipe. * * @param e */ private void handleException(Exception e) { // FIXME this doesn't catch all. For instance, Jetty (6/ NIO) on // Unix like platforms will not be recognized as exceptions // that should be ignored Throwable throwable = e; boolean ignoreException = false; while (throwable != null) { if (throwable instanceof SQLException) { break; // leave false and quit loop } else if (throwable instanceof SocketException) { String message = throwable.getMessage(); ignoreException = message != null && (message.indexOf("Connection reset") != -1 || message.indexOf("Broken pipe") != -1 || message.indexOf("Socket closed") != -1 || message.indexOf("connection abort") != -1); } else { ignoreException = throwable.getClass().getName().indexOf("ClientAbortException") >= 0 || throwable.getClass().getName().indexOf("EofException") >= 0; } if (ignoreException) { if (log.isDebugEnabled()) { log.debug("Socket exception ignored for sending Resource " + "response to client (ClientAbort)", e); } break; } throwable = throwable.getCause(); } if (!ignoreException) { throw new WicketRuntimeException("Unable to write the response", e); } } /** * Copies the given input stream to the servlet response *

* NOTE Content-Length is not set because it would require to buffer the whole input stream *

* * @param in * input stream to copy, will be closed after copy */ public void write(InputStream in) { OutputStream out = getOutputStream(); try { // Copy resource input stream to servlet output stream Streams.copy(in, out); } catch (Exception e) { handleException(e); } finally { // NOTE: We only close the InputStream. The servlet // container should close the output stream. try { in.close(); out.flush(); } catch (IOException e) { // jetty 6 throws broken pipe exception here too handleException(e); } } } /** * Writes the given string to the Response subclass output destination and appends a cr/nl * depending on the OS * * @param string */ public final void println(final CharSequence string) { write(string); write(Strings.LINE_SEPARATOR); } /** * Sets the Content-Type header with servlet-context-defined content-types (application's * web.xml or servlet container's configuration), and fall back to system or JVM-defined * (FileNameMap) content types. * * @param requestCycle * @param uri * Resource name to be analyzed to detect MIME type * * @see ServletContext#getMimeType(String) * @see URLConnection#getFileNameMap() */ public void detectContentType(RequestCycle requestCycle, String uri) { // Configure response with content type of resource final ServletContext context = ((WebApplication)requestCycle.getApplication()).getServletContext(); // First look for user defined content-type in web.xml String contentType = context.getMimeType(uri); // If not found, fall back to // FileResourceStream.getContentType() that looks into // system or JVM content types if (contentType == null) { contentType = URLConnection.getFileNameMap().getContentTypeFor(uri); } if (contentType != null) { // only set the charset when the contentType is the text type if (contentType.toLowerCase().indexOf("text") != -1) { setContentType(contentType + "; charset=" + getCharacterEncoding()); } else { setContentType(contentType); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy