/*
 * 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 gunith.hrapp.service;

import java.net.URL;
import java.util.StringTokenizer;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.engine.ServiceLifeCycle;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.description.AxisService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class SpringInit implements ServiceLifeCycle {

	private static final String SPRING_CONTEXT_FILE_NAMES = "applicationContext.xml";
	private static Log logger = LogFactory.getLog(SpringInit.class);

	// The web service
	public OMElement springInit(OMElement ignore) {

		return null;
	}

	public void init(ServiceContext serviceContext) {

	}

	public void setOperationContext(OperationContext arg0) {

	}

	public void destroy(ServiceContext arg0) {

	}

	/**
	 * this will be called during the deployement time of the service.
	 * irrespective of the service scope this method will be called
	 */
	public void startUp(ConfigurationContext ignore, AxisService service) {
		// ClassLoader classLoader = service.getClassLoader();
		// ClassPathXmlApplicationContext appCtx = new
		// ClassPathXmlApplicationContext(new String[]
		// {"applicationContext.xml"}, false);
		// appCtx.setClassLoader(classLoader);
		// appCtx.refresh();
		// if (logger.isDebugEnabled()) {
		// logger.debug("\n\nstartUp() set spring classloader via axisService.getClassLoader() ... ");
		// }

		// By Default Spring uses Thread.currentThread().getContextClassLoader()
		// to load
		// classes. When in the context of a Axis2 Service, we want to use the
		// Service ClassLoader
		// instead of the context (or in this case webapp) ClassLoader.
		// Therefore, we need to temporarily
		// set the context ClassLoader equal to the Service ClassLoader while we
		// are loading the spring
		// context files. Once the spring context is loaded, we set the context
		// ClassLoader back to
		// what is was before.

		ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

		ClassLoader serviceClassLoader = service.getClassLoader();
		System.out.println(serviceClassLoader.toString());

		Thread.currentThread().setContextClassLoader(serviceClassLoader);

//		String[] springContextFiles = getSpringContextFileNames(service
//				.getParameter(SPRING_CONTEXT_FILE_NAMES).getValue().toString(),
//				serviceClassLoader);

//		ClassPathXmlApplicationContext appCtx = new ClassPathXmlApplicationContext(
//				springContextFiles, false);
		ClassPathXmlApplicationContext appCtx = new ClassPathXmlApplicationContext(
				new String[] { SPRING_CONTEXT_FILE_NAMES }, false);

		// save the spring context in a static class
		Axis2SpringContextHolder.setContext(appCtx);

		appCtx.setClassLoader(serviceClassLoader);
		appCtx.refresh();

		// set the context ClassLoader back to the webapp ClassLoader
		Thread.currentThread().setContextClassLoader(contextClassLoader);

		if (logger.isDebugEnabled()) {
			logger.debug("\n\nstartUp() set spring classloader via axisService.getClassLoader() ... ");
		}
	}

	/**
	 * 
	 * getSpringContextFileNames
	 * 
	 * @param springContextParam
	 *            springContextParam
	 * 
	 * @param cl
	 *            cl
	 * 
	 * @return String[] spring context file names
	 */

	private String[] getSpringContextFileNames(String springContextParam,
			ClassLoader cl) {

		StringTokenizer tokenizer = new StringTokenizer(springContextParam, ",");
		String[] urls = new String[tokenizer.countTokens()];
		int i = 0;

		if (logger.isDebugEnabled()) {
			logger.debug("ClassLoader = " + cl);
			logger.debug("Token count = " + tokenizer.countTokens());
			logger.debug("Context files = " + springContextParam);
		}

		while ((tokenizer.hasMoreTokens())) {

			String contextFile = ((String) tokenizer.nextToken()).trim();
			// URL url = cl.getResource("/" + contextFile);
			URL url = this.getClass().getResource("/" + contextFile);

			if (logger.isDebugEnabled()) {

				logger.debug("find resource /" + contextFile);
				logger.debug("loading spring context file " + url);

			}

			if (url == null) {
				urls[i] = null;
			} else {
				urls[i] = url.toString();
			}

			i++;

		}

		return urls;

	}

	/**
	 * this will be called during the deployement time of the service.
	 * irrespective of the service scope this method will be called
	 */
	public void shutDown(ConfigurationContext ignore, AxisService service) {

	}
}