/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2009 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.web.base.osgi.httpservice;

import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
import org.ow2.jonas.web.base.BaseWebContainerService;


/**
 * ServiceFactory to create {@link HttpService}.
 * @param <T> the web container service class.
 * @author Guillaume Porcher
 * @author Florent Benoit
 */
public abstract class HttpServiceFactory<T extends BaseWebContainerService> implements ServiceFactory {

  /**
   * The web container service (to access catalina/jetty/... instance).
   */
  private final T webContainerService;

  /**
   * The name of the working directory.
   */
  private String workDir;

  /**
   * Constructor.
   * @param webContainerService the web container service to use.
   */
  public HttpServiceFactory(final T webContainerService) {
    this.webContainerService = webContainerService;
  }

  /**
   *  Creates a new {@link HttpService} object.
   *
   *  The Framework invokes this method the first time the specified bundle requests
   *  a service object using the BundleContext.getService(ServiceReference) method.
   *  The service factory can then return a specific service object for each bundle.
   *
   *  The Framework caches the value returned (unless it is null), and will return the
   *  same service object on any future call to BundleContext.getService from the same bundle.
   *
   *  @param callerBundle The bundle using the service.
   *  @param registration The ServiceRegistration object for the service.
   *  @return An instance of HttpService.
   *
   */
  public Object getService(final Bundle callerBundle, final ServiceRegistration registration) {
    webContainerService.startInternalWebContainer();
    return buildHttpServiceImpl(callerBundle, this.webContainerService);
  }

  /**
   * Build an implementation of the Http service.
   * @param callerBundle The bundle using the service.
   * @param webContainerService the web container service instance
   * @return an implementation of the httpService
   */
    protected abstract JOnASHttpService buildHttpServiceImpl(final Bundle callerBundle, final T webContainerService);

  /**
   *  Releases a service object.
   *
   *  The Framework invokes this method when a service has been released by a bundle.
   *  The service object may then be destroyed.
   *
   *  @param callerBundle The bundle releasing the service.
   *  @param registration The ServiceRegistration object for the service.
   *  @param service The service object returned by a previous call
   *                 to the ServiceFactory.getService method.
   */
  public void ungetService(final Bundle callerBundle, final ServiceRegistration registration, final Object service) {
    ((JOnASHttpService) service).stop();
  }

  /**
   * Set the name of the working directory.
   * @param workDir The name of the working directory.
   */
  public void setWorkDirectory(final String workDir) {
    this.workDir = workDir;
  }

  /**
   * @return name of the working directory.
   */
  protected String getWorkDirectory() {
    return this.workDir;
  }

}
