blob: 8d6635157e9392a692c5d4659a19f0972e8ba4df [file] [log] [blame]
/*
* 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.felix.http.base.internal.handler;
import java.io.File;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.dispatch.MultipartConfig;
import org.apache.felix.http.base.internal.logger.SystemLogger;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
import org.osgi.framework.Bundle;
import org.osgi.service.http.runtime.dto.DTOConstants;
/**
* The servlet handler handles the initialization and destruction of
* a servlet.
*/
public abstract class ServletHandler implements Comparable<ServletHandler>
{
private static final String TEMP_DIR = System.getProperty("java.io.tmpdir");
private static final String JAVA_SERVLET_TEMP_DIR_PROP = "javax.servlet.content.tempdir";
private final long contextServiceId;
private final ServletInfo servletInfo;
private final ExtServletContext context;
private volatile Servlet servlet;
protected volatile int useCount;
private final MultipartConfig mpConfig;
public ServletHandler(final long contextServiceId,
final ExtServletContext context,
final ServletInfo servletInfo)
{
this.contextServiceId = contextServiceId;
this.context = context;
this.servletInfo = servletInfo;
final MultipartConfig origConfig = servletInfo.getMultipartConfig();
if ( origConfig != null )
{
String location = origConfig.multipartLocation;
if ( location == null ) {
final Object obj = context == null ? null : context.getAttribute(JAVA_SERVLET_TEMP_DIR_PROP);
if ( obj != null ) {
if ( obj instanceof File ) {
location = ((File)obj).getAbsolutePath();
} else {
location = obj.toString();
}
}
}
if ( location == null ) {
location = TEMP_DIR;
}
this.mpConfig = new MultipartConfig(origConfig.multipartThreshold,
location,
origConfig.multipartMaxFileSize,
origConfig.multipartMaxRequestSize);
}
else
{
this.mpConfig = null;
}
}
@Override
public int compareTo(final ServletHandler other)
{
return this.servletInfo.compareTo(other.servletInfo);
}
public long getContextServiceId()
{
return this.contextServiceId;
}
public ExtServletContext getContext()
{
return this.context;
}
public Servlet getServlet()
{
return servlet;
}
protected void setServlet(final Servlet s)
{
this.servlet = s;
}
public void handle(final ServletRequest req, final ServletResponse res)
throws ServletException, IOException
{
final Servlet local = this.servlet;
if ( local != null )
{
local.service(req, res);
}
else
{
throw new ServletException("Servlet has been unregistered");
}
}
public ServletInfo getServletInfo()
{
return this.servletInfo;
}
public String getName()
{
String name = this.servletInfo.getName();
if (name == null )
{
final Servlet local = this.servlet;
if ( local != null )
{
name = local.getClass().getName();
}
}
return name;
}
/**
* Initialize the object
* @return {code -1} on success, a failure reason according to {@link DTOConstants} otherwise.
*/
public int init()
{
if ( this.useCount > 0 )
{
this.useCount++;
return -1;
}
if (this.servlet == null)
{
return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
}
try
{
servlet.init(new ServletConfigImpl(getName(), getContext(), getServletInfo().getInitParameters()));
}
catch (final Exception e)
{
SystemLogger.error(this.getServletInfo().getServiceReference(),
"Error during calling init() on servlet " + this.servlet,
e);
return DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT;
}
this.useCount++;
return -1;
}
public boolean destroy()
{
if (this.servlet == null)
{
return false;
}
this.useCount--;
if ( this.useCount == 0 )
{
try
{
servlet.destroy();
}
catch ( final Exception ignore )
{
// we ignore this
SystemLogger.error(this.getServletInfo().getServiceReference(),
"Error during calling destroy() on servlet " + this.servlet,
ignore);
}
servlet = null;
return true;
}
return false;
}
public boolean dispose()
{
// fully destroy the servlet
this.useCount = 1;
return this.destroy();
}
@Override
public int hashCode()
{
return 31 + servletInfo.hashCode();
}
@Override
public boolean equals(final Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null || getClass() != obj.getClass() )
{
return false;
}
final ServletHandler other = (ServletHandler) obj;
return servletInfo.equals(other.servletInfo);
}
public MultipartConfig getMultipartConfig()
{
return mpConfig;
}
public Bundle getMultipartSecurityContext()
{
return null;
}
}