All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jwall.apache.httpd.config.ApacheConfig Maven / Gradle / Ivy

The newest version!
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *   Copyright (C) 2010-2014 Christian Bockermann 
 *    
 *   This file is part of the jwall.org apache-config library. The apache-config library is
 *   a parsing library to handle Apache HTTPD configuration files.
 *
 *   More information and documentation for the jwall-tools can be found at
 *   
 *                      http://www.jwall.org/apache-config
 *   
 *   This program is free software; you can redistribute it and/or modify it under
 *   the terms of the GNU General Public License as published by the Free Software
 *   Foundation; either version 3 of the License, or (at your option) any later version.
 *   
 *   This program 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 General Public License for more details.
 * 
 *   You should have received a copy of the GNU General Public License along with this 
 *   program; if not, see .
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package org.jwall.apache.httpd.config;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

public class ApacheConfig extends ContainerDirective {
	/** The unique class id */
	private static final long serialVersionUID = 1138652213682863902L;

	public static Class[] APACHE_CONFIG_CLASSES = { ApacheConfig.class,
			LineDirective.class, ContainerDirective.class, Directive.class,
			Comment.class, DocumentRoot.class, Directory.class, SecRule.class,
			RewriteRule.class, FilesMatch.class, IfModule.class, Include.class,
			VirtualHost.class, SecAction.class, SecRule.class };

	/** A class global logger */
	static Logger log = Logger.getLogger("ApacheConfig");

	/** A list of possibly included configurations */
	List subTrees = new LinkedList();

	/**
	 * A list of virtual host environments, defined in this configuration
	 * instance
	 */
	List vhosts = new LinkedList();

	/** The file from which the configuration has been parsed */
	File file;

	/**
	 * Time stamp of the last time the file was read, i.e. the time this
	 * configuration has been created
	 */
	Long readAt = 0L;

	/**
	 * In case this instance is a nested child, this string does provide the
	 * file name and line-number of the file where it has been included, i.e.
	 * the location of the include directive.
	 */
	String includedBy = null;

	String md5sum = "";

	/**
	 * Create a new instance of this class which is associated to the given
	 * file. The instance is initially empty and will not automatically parse
	 * the file.
	 * 
	 * @param file
	 *            The file to which this configuration is associated.
	 */
	public ApacheConfig(File file) {
		super(file.getAbsolutePath(), file, 0);
		log.fine("Creating ApacheConfig off " + file.getAbsolutePath());

		this.readAt = System.currentTimeMillis();
		this.subTrees = new LinkedList();
		this.file = file;
		this.name = "ApacheConfig";
	}

	/**
	 * @return the md5sum
	 */
	public String getMd5sum() {
		return md5sum;
	}

	/**
	 * @param md5sum
	 *            the md5sum to set
	 */
	public void setMd5sum(String md5sum) {
		this.md5sum = md5sum;
	}

	/**
	 * Returns a list of file which contains the file associated to this
	 * instance and all files related to nested configurations, i.e. a list of
	 * all files relevant for the complete Apache configuration denoted by this
	 * instance.
	 * 
	 * @return The list of referenced files, including the file associated to
	 *         this instance.
	 */
	public List getFiles() {
		List files = new LinkedList();
		files.add(file);

		for (ApacheConfig cfg : subTrees)
			files.addAll(cfg.getFiles());

		return files;
	}

	/**
	 * This method returns the time stamp of the file that has most lately been
	 * changed.
	 * 
	 * @return
	 */
	public long lastModified() {
		long lm = file.lastModified();
		return lm;
	}

	/**
	 * This method return the time stamp of the moment when this config has been
	 * parsed.
	 * 
	 * @return
	 */
	public long lastRead() {
		return readAt;
	}

	public boolean hasChanged() {
		log.finest("Last modified: " + new Date(file.lastModified()));
		log.finest("Last read: " + new Date(lastRead()));
		boolean changed = lastRead() < this.file.lastModified();
		if (changed)
			return true;

		log.finest("This config has " + subTrees.size() + " inclusions.");
		for (ApacheConfig ch : this.subTrees) {
			log.finest("Checking included child " + ch.getFile());
			if (ch.hasChanged())
				return true;
		}

		return changed;
	}

	public void add(AbstractDirective d) {
		// log.fine(prefix()+"Calling add(Directive)");
		super.add(d);
		if (d instanceof ApacheConfig) {
			ApacheConfig sub = (ApacheConfig) d;
			subTrees.add(sub);
		}

		if (d instanceof VirtualHost) {
			VirtualHost vh = (VirtualHost) d;
			vhosts.add(vh);
		}

		if (d instanceof Include) {
			// System.out.println("Include directive added... " );
			Include include = (Include) d;
			for (Directive dir : include.getChildren()) {

				if (dir instanceof ApacheConfig) {
					ApacheConfig included = (ApacheConfig) dir;
					// System.out.println( "\tAdding sub config..." );
					subTrees.add(included);
				}

			}
		}
	}

	public void add(ApacheConfig cfg) {
		log.fine("ApacheConfig[" + file.getAbsolutePath()
				+ "] gets new child: " + cfg.file.getAbsolutePath());
		cfg.parent = this;
		super.add(cfg);
		subTrees.add(cfg);
	}

	public List getSubTrees() {
		LinkedList sub = new LinkedList();
		sub.addAll(subTrees);
		for (ApacheConfig subcfg : subTrees) {
			for (ApacheConfig ch : subcfg.getSubTrees()) {
				if (!sub.contains(ch))
					sub.add(ch);
			}
		}

		return sub;
	}

	public List getVirtualHosts() {
		List vh = new LinkedList();

		vh.addAll(vhosts);
		for (ApacheConfig sub : subTrees)
			vh.addAll(sub.getVirtualHosts());

		return vh;
	}

	public List getAllVirtualHosts() {

		List vh = getVirtualHosts();

		for (ApacheConfig cfg : getSubTrees())
			vh.addAll(cfg.getAllVirtualHosts());

		return vh;
	}

	public String toString() {
		if (parent == null)
			return file.getAbsolutePath();

		File parentFile = null;
		parentFile = parent.getLocation().getFile();

		if (parentFile.getParent() != null
				&& file.getAbsolutePath().startsWith(parentFile.getParent()))
			return file.getName();
		else
			return file.getAbsolutePath();
	}

	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	public String toTree() {
		StringBuffer s = new StringBuffer();

		s.append(prefix() + " " + file.getAbsolutePath() + "\n");
		for (ApacheConfig cfg : subTrees)
			s.append(cfg.toTree());

		return s.toString();
	}

	public String toPlainTxt() {
		StringBuffer s = new StringBuffer();

		for (Directive d : nested) {

			if ((d instanceof ApacheConfig) || "Include".equals(d.getName())) {
				// s.append( d.rawLine + "\n");
			} else
				s.append(d.toPlainTxt() + "\n");
		}

		return s.toString();
	}

	public String toXML() {

		/*
		 * return getXStream().toXML( this );
		 */

		StringBuffer s = new StringBuffer();

		s.append(prefix() + "<" + name + " file=\""
				+ this.file.getAbsolutePath() + "\"");

		if (this.includedBy != null && !"".equals(includedBy.trim()))
			s.append(" includedAt=\"" + includedBy + "\"");

		s.append(">\n");

		for (Directive d : nested)
			s.append(d.toXML() + "\n");

		s.append(prefix() + "\n");

		return s.toString();
	}

	public List findDirectiveByName(String name, boolean recursive) {
		List found = new LinkedList();

		for (Directive d : this.getChildren()) {
			if (d.getName().matches(name) || d.matches(name))
				found.add(d);

			if (recursive && (d instanceof ContainerDirective)) {
				ContainerDirective c = (ContainerDirective) d;
				found.addAll(c.findDirectiveByName(name, recursive));
			}
		}

		if (recursive)
			for (ApacheConfig subConfig : subTrees)
				found.addAll(subConfig.findDirectiveByName(name, recursive));

		return found;
	}

	public void setIncludedBy(String s) {
		includedBy = s;
	}

	public String getIncludedBy() {
		return includedBy;
	}

	public List getReferencedFiles() {
		return new ArrayList();
	}

	public static ApacheConfig parse(File f) throws Exception {
		ConfigParser p = new ConfigParser(f);
		ApacheConfig cfg = p.parseConfig();
		return cfg;
	}

	/*
	 * public static XStream getXStream(){ XStream xs = new XStream();
	 * xs.processAnnotations( APACHE_CONFIG_CLASSES ); return xs; }
	 */

	public String toXML(ApacheConfig cfg) {

		StringBuffer s = new StringBuffer("<" + name + " file=\"");
		s.append(this.location.toString());
		s.append("\">\n");

		for (Directive child : this.nested) {
			s.append(child.toXML());
		}

		s.append("\n");
		return s.toString();
		// return getXStream().toXML( cfg );
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy