blob: 6976bae6653548cf51ec443e51e6825bc02068a9 [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.ace.http.listener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServlet;
import org.apache.ace.http.listener.constants.HttpConstants;
import org.apache.felix.dm.DependencyActivatorBase;
import org.apache.felix.dm.DependencyManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import org.osgi.service.log.LogService;
/**
* Service responsible for registrating HttpServlets at HttpServices.<p>
*
* When a HttpServlet is being added or removed, the callback methods in this class are being
* called via the DependencyManager. A Servlet is being added to all HttpServices currently
* available or removed from all available HttpServices.<p>
*
* In case a HttpService is being added or removed, other callback methods are being called
* via the DependencyManager. When a HttpService is added, all previously registered Servlets
* are being registered to this new HttpService. In case of removal, all Servlet endpoints are
* being removed from the HttpService that is going to be removed.<p>
*/
public class Activator extends DependencyActivatorBase {
private volatile LogService m_log; // injected
private final Set<ServiceReference> m_httpServices = new HashSet<ServiceReference>();
private final Map<ServiceReference, String> m_servlets = new HashMap<ServiceReference, String>();
private BundleContext m_context;
@Override
public synchronized void init(BundleContext context, DependencyManager manager) throws Exception {
m_context = context;
manager.add(createComponent()
.setImplementation(this)
.add(createServiceDependency()
.setService(LogService.class)
.setRequired(false))
.add(createServiceDependency()
.setService(HttpService.class)
.setAutoConfig(false)
.setCallbacks("addHttpService", "removeHttpService"))
.add(createServiceDependency()
.setService(HttpServlet.class)
.setAutoConfig(false)
.setCallbacks("addHttpServlet", "changeHttpServlet", "removeHttpServlet")));
}
/**
* Callback method used in case a HttpServlet is being added. This Servlet is being added
* to all available HttpServices under the endpoint configured via the Configurator.
*
* @param ref reference to the Servlet
*/
public synchronized void addHttpServlet(ServiceReference ref) {
// register servlet to all HttpServices
String endpoint = (String)ref.getProperty(HttpConstants.ENDPOINT);
m_servlets.put(ref, endpoint);
Servlet servlet = (Servlet)m_context.getService(ref);
for (ServiceReference reference : m_httpServices) {
HttpService httpService = (HttpService) m_context.getService(reference);
try {
if ((httpService != null) && (endpoint != null) && (servlet != null)) {
httpService.registerServlet(endpoint, servlet, null, null);
}
else {
m_log.log(LogService.LOG_WARNING, "Unable to register servlet with endpoint '" + endpoint + "'");
}
}
catch (Exception e) {
m_log.log(LogService.LOG_WARNING, "Already registered under existing endpoint", e);
}
}
}
public synchronized void changeHttpServlet(ServiceReference ref) {
removeServlet(ref, m_servlets.get(ref));
addHttpServlet(ref);
}
/**
* Callback method used in case a HttpServlet is being removed. This Servlet is being removed
* from all available HttpServices using the endpoint configured via the Configurator.
*
* @param ref reference to the Servlet
*/
public synchronized void removeHttpServlet(ServiceReference ref) {
// remove servlet from all HttpServices
String endpoint = (String)ref.getProperty(HttpConstants.ENDPOINT);
removeServlet(ref, endpoint);
}
private void removeServlet(ServiceReference ref, String endpoint) {
m_servlets.remove(ref);
for (ServiceReference reference : m_httpServices) {
HttpService httpService = (HttpService) m_context.getService(reference);
if ((httpService != null) && (endpoint != null)) {
try {
httpService.unregister(endpoint);
}
catch (Exception e) {
m_log.log(LogService.LOG_WARNING, "Servlet cannot be unregistered, maybe not registered under this endpoint", e);
}
}
}
}
/**
* Callback method used in case a HttpService is being added. To this Service all previously
* registered Servlet are added under the endpoints of the Servlets (which are configured
* via the Configurator).
*
* @param ref reference to the Service
*/
public synchronized void addHttpService(ServiceReference ref, HttpService httpService) {
m_httpServices.add(ref);
// register all servlets to this new HttpService
for (ServiceReference reference : m_servlets.keySet()) {
Servlet servlet = (Servlet)m_context.getService(reference);
String endpoint = (String)reference.getProperty(HttpConstants.ENDPOINT);
if ((servlet != null) && (endpoint != null)) {
try {
httpService.registerServlet(endpoint, servlet, null, null);
}
catch (Exception e) {
m_log.log(LogService.LOG_WARNING, "Already registered under existing endpoint", e);
}
}
}
}
/**
* Callback method used in case a HttpService is being removed. From this Service all previously
* registered Servlet are removed using the endpoints of the Servlets (which are configured
* via the Configurator).
*
* @param ref reference to the Service
*/
public synchronized void removeHttpService(ServiceReference ref, HttpService httpService) {
m_httpServices.remove(ref);
// remove references from the unregistered HttpService
unregisterEndpoints(httpService);
}
@Override
public synchronized void destroy(BundleContext context, DependencyManager arg1) throws Exception {
for (ServiceReference httpRef : m_httpServices) {
HttpService httpService = (HttpService)m_context.getService(httpRef);
if (httpService != null) {
unregisterEndpoints(httpService);
}
}
m_httpServices.clear();
m_servlets.clear();
m_context = null;
}
/**
* Unregisters all Servlets (via their endpoints) from the HttpService being passed to
* this method.
*
* @param httpService the HttpService that is being unregistered
*/
private void unregisterEndpoints(HttpService httpService) {
for (ServiceReference reference : m_servlets.keySet()) {
String endpoint = (String)reference.getProperty(HttpConstants.ENDPOINT);
if (endpoint != null) {
try {
httpService.unregister(endpoint);
}
catch (Exception e) {
m_log.log(LogService.LOG_WARNING, "Servlet cannot be unregistered, maybe not registered under this endpoint", e);
}
}
}
}
}