org.rhq.plugins.apache.augeas.ApacheAugeasTree 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-2009 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, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* 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 and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.plugins.apache.augeas;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.augeas.Augeas;
import org.rhq.augeas.config.AugeasModuleConfig;
import org.rhq.augeas.node.AugeasNode;
import org.rhq.augeas.tree.AugeasTreeException;
import org.rhq.augeas.tree.impl.AugeasTreeLazy;
/**
* For Apache, we need our own implementation of the tree
* because we need to build the tree such that it transparently
* handles the include directives (i.e. the call to {@link #match(String)}
* or {@link #matchRelative(AugeasNode, String)} should return
* nodes as if the Include directive was replaced by the contents
* of the included file.
*
* @author Lukas Krejci
* @author Filip Drabek
*/
public class ApacheAugeasTree extends AugeasTreeLazy {
private Map> includes;
private List includeGlobs;
public ApacheAugeasTree(String serverRootPath, Augeas ag, AugeasModuleConfig moduleConfig) {
super(ag, moduleConfig);
this.includeGlobs = initIncludeGlobs(serverRootPath);
}
protected AugeasNode instantiateNode(String fullPath) {
return new ApacheAugeasNode(fullPath, this);
}
public Map> getIncludes() {
return includes;
}
public void setIncludes(Map> includes) {
this.includes = includes;
}
public List match(String expression) throws AugeasTreeException {
if (!expression.startsWith(AUGEAS_DATA_PATH))
expression = AUGEAS_DATA_PATH + expression;
/*AugeasNode node = null;
int max = 0;
for (AugeasNode nd : includes.keySet()) {
for (String file : includes.get(nd)) {
if (expression.startsWith(file)) {
if (file.length() > max) {
node = nd;
max = file.length();
}
}
}
}
if (node == null){
node = rootNode;
max = rootNode.getFullPath().length();
}
return matchRelative(node, expression.substring(max + 1));*/
return matchInternal(expression);
}
public List matchRelative(AugeasNode node, String expression) throws AugeasTreeException {
try {
if (expression.indexOf(PATH_SEPARATOR) == 0)
expression = expression.substring(1);
return parseExpr(node, expression);
} catch (Exception e) {
throw new AugeasTreeException(e.getMessage());
}
}
@Override
protected List getIncludeGlobs() {
return includeGlobs;
}
private int subExpressionIndex(String expr) {
//we have to parse the expression carefully because of the
//potential xpath qualifier that can contain path separators.
//0 = normal
//1 = in xpath qualifier
//2 = in double-quoted string (inside the qualifier)
//3 = in single-quoted string (inside the qualifier)
int state = 0;
int idx = 0;
boolean found = false;
while (!found && idx < expr.length()) {
char currentChar = expr.charAt(idx);
switch (state) {
case 0: //normal
switch (currentChar) {
case '[':
state = 1;
break;
case '/':
found = true;
break;
}
break;
case 1: //xpath qualifier
switch (currentChar) {
case ']':
state = 0;
break;
case '"':
state = 2;
break;
case '\'':
state = 3;
break;
}
break;
case 2: //double quoted string
switch (currentChar) {
case '"':
state = 1;
break;
case '\\':
idx++;
break;
}
break;
case 3: //single quoted string
switch (currentChar) {
case '\'':
state = 1;
break;
case '\\':
idx++;
break;
}
break;
}
idx++;
}
return idx == expr.length() ? -1 : idx;
}
private List parseExpr(AugeasNode nd, String expr) throws Exception {
int index = subExpressionIndex(expr);
if (index == -1)
return search(nd, expr);
String subExpr = expr.substring(0, index - 1);
List nodes = search(nd, subExpr);
List nds = new ArrayList();
for (AugeasNode node : nodes) {
List tempNodes = parseExpr(node, expr.substring(index));
if (tempNodes != null)
nds.addAll(tempNodes);
}
return nds;
}
private List search(AugeasNode nd, String expr) throws Exception {
String fullExpr = nd.getFullPath() + PATH_SEPARATOR + expr;
List nodes = this.matchInternal(fullExpr);
if (includes.containsKey(nd)) {
List files = includes.get(nd);
for (String fileName : files) {
List nds = this.matchInternal(fileName + PATH_SEPARATOR + expr);
for (AugeasNode node : nds) {
if (!nodes.contains(node))
nodes.add(node);
}
}
}
return nodes;
}
private List matchInternal(String expression) throws AugeasTreeException {
if (!expression.startsWith(AUGEAS_DATA_PATH))
expression = AUGEAS_DATA_PATH + expression;
List res = getAugeas().match(expression);
List nodes = new ArrayList();
for (String name : res) {
nodes.add(getNode(name));
}
return nodes;
}
/**
* @param serverRootPath
* @return
*/
private List initIncludeGlobs(String serverRootPath) {
ArrayList ret = new ArrayList();
for (String glob : getModuleConfig().getIncludedGlobs()) {
File f = new File(glob);
if (f.isAbsolute()) {
ret.add(glob);
} else {
ret.add(new File(serverRootPath, glob).getPath());
}
}
return ret;
}
}