How to get WEB-INF path outside Java servlet

Here is basic class, which is a mix on many comments everywhere about how to get the WEB-INF path.
The class is a singleton class to not perform WEB-INF check everytime, it helps to keep good performance. It is designed to find the good WEB-INF without any knowledge of package or servlet context. It uses many small trick to find the WEB-INF folder. I also include a basic « how to find a config.xml file » to create your own custom config file, and be able to access it outside servlet.

Update 2012-12-07 : the classpath was having trouble using space character : it was HTML escaped one (%20), so I add a simple replaceAll to correct that behaviour. Other HTML escape should probably not be needed but please keep in mind it can happen !

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * This class search for the web inf class path and gives many path from that
 * Licence LGPLv3
 * Publish 2012-10-03
 * @author Deisss
 * @version 0.1
 */
public class ClassPath{
	private static ClassPath instance = null;
	private String webInfPath, webXmlPath, configXmlPath;

	/**
	 * The constructor will get the webInfPath and store it until the app close
	 */
	private ClassPath(){
		File myClass = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getFile());

		//The package name give the number of parentFile to apply
		//We add 3 : the first one is the .class name, the "." counted are one less, and the package is
		//inside a classes folder. So 3.
		int packageSubFolder = getClass().getPackage().getName().replaceAll("[^.]", "").length() + 3;

		//Place the file to the good parent file to point into the web inf
		for(int i=0; i<packageSubFolder; i++){
			myClass = myClass.getParentFile();
		}

		this.webInfPath = myClass.getAbsolutePath().replaceAll("%20", " ") + File.separator;
		this.webXmlPath = this.getWebInfPath() + "web.xml";
		this.configXmlPath = this.getWebInfPath() + "config.xml";
	}

	/**
	 * Singleton structure
	 * @return himself
	 */
	public static ClassPath getInstance(){
		if(instance == null){
			instance = new ClassPath();
		}
		return instance;
	}


	/**
	 * Get back the WEB-INF path
	 * @return The WEB-INF path
	 */
	public String getWebInfPath(){
		return this.webInfPath;
	}

	/**
	 * Get back the WEB-INF/web.xml path
	 * @return The WEB-INF/web.xml path
	 */
	public String getWebXmlPath(){
		return this.webXmlPath;
	}

	/**
	 * Get back the WEB-INF/config.xml path
	 * @return The WEB-INF/config.xml path
	 */
	public String getConfigXmlPath(){
		return this.configXmlPath;
	}
}

Now you can put this file in every package, using the package name it will be able to find the good path from /WEB-INF/classes to himself. Doing so it can be put in any place it will still be able to get the good WEB-INF path (of course it must be a web project at least…). Here is an example how to use it :

File file = new File(ClassPath.getInstance().getConfigXmlPath());
DataInputStream dis = null;

try{
	dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
	while(dis.available() != 0){
		System.out.println(dis.readLine());
	}
	dis.close();
}catch(FileNotFoundException e){
	e.printStackTrace();
}catch(IOException e){
	e.printStackTrace();
}

That’s it, it will read the full config.xml inside WEB-INF folder.

Publicités

2 Commentaires

  1. Ciro Cardone

    Good job boy!

    This code works only if ClassPath.class is in WEB-INF/classes, but not if it is in a JAR library.

    Is there an elegant solution to achieve same result?

    Thanks

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :