package net.anotheria.moskito.webui.more.action;

import net.anotheria.maf.action.ActionCommand;
import net.anotheria.maf.action.ActionMapping;
import net.anotheria.maf.bean.FormBean;
import net.anotheria.moskito.webui.more.bean.WebappLibBean;
import net.anotheria.util.NumberUtils;
import net.anotheria.util.maven.MavenVersionReader;
import org.apache.log4j.Logger;

import javax.management.BadAttributeValueExpException;
import javax.management.BadBinaryOpValueExpException;
import javax.management.BadStringOperationException;
import javax.management.InvalidApplicationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * This action scans and displays current libs.
 *
 * @author lrosenberg
 * @since 28.10.12 23:41
 */
public class ShowLibsAction extends BaseAdditionalAction{
	/**
	 * Logger.
	 */
	private static Logger log = Logger.getLogger(ShowLibsAction.class);

	@Override
	protected String getLinkToCurrentPage(HttpServletRequest req) {
		return null;  //To change body of implemented methods use File | Settings | File Templates.
	}

	@Override
	public ActionCommand execute(ActionMapping mapping, FormBean formBean, HttpServletRequest req, HttpServletResponse res) throws Exception {

		List<URL> classpath = getClassPathUrls(req.getContextPath());
		List<WebappLibBean> beans = new ArrayList<WebappLibBean>();

		for (URL url : classpath){
			String fileName = url.getFile();
			if (!fileName.endsWith(".jar"))
				continue;
			File f = new File(fileName);
			WebappLibBean bean = new WebappLibBean();
			int lastSlash = fileName.lastIndexOf('/');
			try{
				bean.setName(fileName.substring(lastSlash + 1));
				bean.setMavenVersion(MavenVersionReader.readVersionFromJar(f));
				if (bean.getMavenVersion()==null){
					bean.setLastModified(NumberUtils.makeISO8601TimestampString(f.lastModified()));
				}
			}catch(Exception e){
				log.warn("couldn't obtain lib version, skipped this url "+url, e);
			}
			beans.add(bean);

		}
		req.setAttribute("beansCount", beans.size());
		req.setAttribute("beans", beans);

		return mapping.success();

	}

	private List<URL> getClassPathUrls(final String context){
		List<URL> forTomcat = getClassPathUrlsForTomcat(context);
		if (forTomcat!=null && forTomcat.size()>0)
			return forTomcat;
		//add another lookup methods here.
		return new ArrayList<URL>();

	}

	private List<URL> getClassPathUrlsForTomcat(final String context){
		List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
		for (MBeanServer s : servers){
			Set<ObjectInstance> instances = s.queryMBeans(null, new QueryExp() {
				@Override
				public boolean apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException {
					String type = name.getKeyProperty("type");
					if (!type.equals("WebappClassLoader"))
						return false;
					if (!name.getDomain().equals("Catalina"))
						return false;
					if (!name.getKeyProperty("context").equals(context))
						return false;
					return true;
				}

				@Override
				public void setMBeanServer(MBeanServer s) {
				}
			});
			if (instances.size()>0){
				try{
					URL[] urls = (URL[])s.getAttribute(instances.iterator().next().getObjectName(), "URLs");
					return Arrays.asList(urls);
				}catch(Exception e){}

			}
		}
		return null;
	}

}

@@ -2529,16 +2529,17 @@
 orTomcat
+7
  = getCl
@@ -2558,16 +2558,17 @@
 orTomcat
+7
 (context
@@ -2585,16 +2585,17 @@
 orTomcat
+7
 !=null &
@@ -2605,16 +2605,17 @@
 orTomcat
+7
 .size()%3E
@@ -2636,16 +2636,148 @@
 orTomcat
+7;%0A%09%09List%3CURL%3E forTomcat6 = getClassPathUrlsForTomcat6(context);%0A%09%09if (forTomcat6!=null && forTomcat6.size()%3E0)%0A%09%09%09return forTomcat6
 ;%0A%09%09//ad
@@ -2887,16 +2887,17 @@
 orTomcat
+7
 (final S
@@ -2908,24 +2908,382 @@
 g context)%7B%0A
+%09%09return getClassPathUrlsForTomcat(context, %22context%22);%0A%09%7D%0A%0A%09private List%3CURL%3E getClassPathUrlsForTomcat6(final String context)%7B%0A%09%09return getClassPathUrlsForTomcat(context, %22path%22);%0A%09%7D%0A%0A%09private List%3CURL%3E getClassPathUrlsForTomcat(final String context, final String contextPropertyName)%7B%0A%09%09System.out.println(%22checking class path urls for tomcat %22+context);%0A
 %09%09List%3CMBean
@@ -3839,25 +3839,35 @@
 roperty(
-%22
 context
-%22
+PropertyName
 ).equals
@@ -3893,24 +3893,66 @@
 turn false;%0A
+%09%09%09%09%09System.out.println(%22Found - %22+name);%0A
 %09%09%09%09%09return 

fix for tomcat 6