org.rhq.plugins.apache.parser.ApacheParserImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rhq-apache-plugin Show documentation
Show all versions of rhq-apache-plugin Show documentation
a plugin for managing Apache web servers (1.3 and later)
/*
* RHQ Management Platform
* Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* 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 version 2 of the License.
*
* 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.plugins.apache.parser;
import java.io.File;
import java.util.List;
import org.rhq.augeas.util.Glob;
import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
import org.rhq.plugins.apache.util.RuntimeApacheConfiguration;
/**
*
* @author Filip Drabek
* @author Lukas Krejci
*/
public class ApacheParserImpl implements ApacheParser {
private final static String INCLUDE_DIRECTIVE = "Include";
private static final String SERVER_ROOT_DIRECTIVE = "ServerRoot";
private final ApacheDirectiveTree tree;
private ApacheDirectiveStack stack;
private String serverRootPath;
private RuntimeApacheConfiguration.NodeInspector nodeInspector;
/**
*
* @param tree the tree that this parser will fill in
* @param initialServerRootPath the initial server root path as detected by other means
* @param nodeInspector the node inspector to determine the runtime configuration or null, if full configuration tree is needed
*/
public ApacheParserImpl(ApacheDirectiveTree tree, String initialServerRootPath,
RuntimeApacheConfiguration.NodeInspector nodeInspector) {
stack = new ApacheDirectiveStack();
this.serverRootPath = initialServerRootPath;
this.tree = tree;
stack.addDirective(this.tree.getRootNode());
this.nodeInspector = nodeInspector;
}
public void addDirective(ApacheDirective directive) throws Exception {
if (stack.getLastDirective() == null) {
//we're ignoring until the end of an ignored nested directive
return;
}
if (directive.getName().equals(INCLUDE_DIRECTIVE)) {
List files = getIncludeFiles(directive.getValuesAsString());
for (File fl : files) {
if (fl.exists() && fl.isFile()) {
ApacheConfigReader.searchFile(fl.getAbsolutePath(), this);
}
}
} else if (directive.getName().equals(SERVER_ROOT_DIRECTIVE)) {
this.serverRootPath = AugeasNodeValueUtil.unescape(directive.getValuesAsString());
}
if (nodeInspector != null) {
//let the inspector process this directive in case it sees something of interest
nodeInspector.inspect(directive.getName(), directive.getValues(), directive.getValuesAsString());
}
directive.setParentNode(stack.getLastDirective());
stack.getLastDirective().addChildDirective(directive);
}
public void endNestedDirective(ApacheDirective directive) {
stack.removeLastDirective();
}
public void startNestedDirective(ApacheDirective directive) {
if (nodeInspector != null) {
//now we have a node inspector so the tree construction is driven by it - we actually leave out the conditional
//directives and replace them with their contents (if they are to be applied of course)...
RuntimeApacheConfiguration.NodeInspectionResult res =
nodeInspector.inspect(directive.getName(), directive.getValues(), directive.getValuesAsString());
if (res == null || (res.nodeIsConditional && !res.shouldRecurseIntoConditionalNode)) {
//ok, this node should be ignored, mark that fact with a null parent
stack.addDirective(null);
} else if (res.nodeIsConditional && res.shouldRecurseIntoConditionalNode) {
//this is a little tricky..
//we need to leave out this directive, because it is conditional and we should be replacing it with its contents
//but also we need to keep the stack balanced (i.e. we're going down a nested directive, so we ought to put something
//on the stack). By duplicating the last known directive on the stack we actually achieve both of the goals - the
//stack remains balanced and the child nodes get added to the parent of this directive (i.e. in the end it is going to
//look like we've replaced the directive with its child directives).
stack.addDirective(stack.getLastDirective());
} else {
//ok, a "normal" (non-conditional) nested node
//we might be inside an ignored nested directive, so leave all the weaving stuff
//out in that case...
if (stack.getLastDirective() != null) {
directive.setParentNode(stack.getLastDirective());
stack.getLastDirective().addChildDirective(directive);
}
stack.addDirective(directive);
}
} else {
//there is no node inspector, so we have no "guidance" on the tree construction.
//Just include all the nested structures so that a full configuration tree is built
//with all the directives.
//we might be inside an ignored nested directive, so leave all the weaving stuff
//out in that case...
if (stack.getLastDirective() != null) {
directive.setParentNode(stack.getLastDirective());
stack.getLastDirective().addChildDirective(directive);
}
stack.addDirective(directive);
}
}
private List getIncludeFiles(String foundInclude) {
File check = new File(foundInclude);
File root = new File(check.isAbsolute() ? Glob.rootPortion(foundInclude) : serverRootPath);
return Glob.match(root, foundInclude, Glob.ALPHABETICAL_COMPARATOR);
}
}