//----------------------------BEGIN LICENSE----------------------------
/* 
 * Willow : the Open Source WorkFlow Project
 * Distributable under GNU LGPL license by gun.org
 *
 * Copyright (C) 2004-2010  huihoo.org 
 * Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com> 
 * 
 * ====================================================================
 * Project Homepage : http://www.huihoo.org/willow
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : willow@lists.sourceforge.net 
 */
//----------------------------END  LICENSE-----------------------------
package org.huihoo.willow.xmlrules;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.huihoo.willow.Context;
import org.huihoo.willow.Deployer;
import org.huihoo.willow.Service;
import org.huihoo.willow.Globals;
import org.huihoo.willow.core.StandardService;
import org.huihoo.willow.startup.ExpandWar;
import org.xml.sax.Attributes;

public class SetDocBaseRule extends Rule
{

	// ----------------------------------------------------------- Constructors

	/**
	 * Construct a new instance of this Rule.
	 *
	 * @param digester Digester we are associated with
	 */
	public SetDocBaseRule(Digester digester)
	{

		super(digester);

	}

	// ----------------------------------------------------- Instance Variables

	// --------------------------------------------------------- Public Methods

	/**
	 * Handle the beginning of an XML element.
	 *
	 * @param attributes The attributes of this element
	 *
	 * @exception Exception if a processing error occurs
	 */
	public void begin(Attributes attributes) throws Exception
	{
		Context child = (Context) digester.peek(0);
		Deployer parent = (Deployer) digester.peek(1);
		Service engine = null;
		if (!(parent instanceof StandardService))
		{
			Method method = parent.getClass().getMethod("getService", null);
			engine = (Service) method.invoke(parent, null);
		}
		else
		{
			engine = (Service) parent;
		}
		String appBase = engine.getAppBase();

		boolean unpackWARs = true;
		if (engine instanceof StandardService)
		{
			unpackWARs = ((StandardService) engine).isUnpackWARs();
		}
		if (!unpackWARs && !("true".equals(attributes.getValue("unpackWAR"))))
		{
			return;
		}
		if ("false".equals(attributes.getValue("unpackWAR")))
		{
			return;
		}

		File canonicalAppBase = new File(appBase);
		if (canonicalAppBase.isAbsolute())
		{
			canonicalAppBase = canonicalAppBase.getCanonicalFile();
		}
		else
		{
			canonicalAppBase = new File(System.getProperty(Globals.PROPS_WILLOW_HOME), appBase).getCanonicalFile();
		}

		String docBase = child.getDocBase();
		if (docBase == null)
		{
			// Trying to guess the docBase according to the path
			String name = child.getName();
			if (name == null)
			{
				return;
			}
			if (name.equals(""))
			{
				docBase = Globals.DEFAULT_WORKFLOW;
			}
			else
			{
				docBase = name;
			}
		}

		File file = new File(docBase);
		if (!file.isAbsolute())
		{
			docBase = (new File(canonicalAppBase, docBase)).getPath();
		}
		else
		{
			docBase = file.getCanonicalPath();
		}

		if (docBase.toLowerCase().endsWith(".war"))
		{
			URL war = new URL("jar:" + (new File(docBase)).toURL() + "!/");
			String contextName = child.getName();
			if (contextName.equals(""))
			{
				contextName = Globals.DEFAULT_WORKFLOW;
			}
			docBase = ExpandWar.expand(engine, war, contextName);
			file = new File(docBase);
			docBase = file.getCanonicalPath();
		}
		else
		{
			File docDir = new File(docBase);
			if (!docDir.exists())
			{
				File warFile = new File(docBase + ".war");
				if (warFile.exists())
				{
					URL war = new URL("jar:" + warFile.toURL() + "!/");
					docBase = ExpandWar.expand(engine, war, child.getName());
					file = new File(docBase);
					docBase = file.getCanonicalPath();
				}
			}
		}

		if (docBase.startsWith(canonicalAppBase.getPath()))
		{
			docBase = docBase.substring(canonicalAppBase.getPath().length() + 1);
		}
		docBase = docBase.replace(File.separatorChar, '/');

		child.setDocBase(docBase);

	}

}
