move to native ptql impl
This commit is contained in:
parent
3ffa2335c3
commit
ff7fd11fac
|
@ -3,12 +3,10 @@
|
|||
<classpathentry kind="src" path="build/src"/>
|
||||
<classpathentry kind="src" path="hyperic_jni/src"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry sourcepath="/usr/src/jakarta/bcel-5.1/src/java/" kind="lib" path="lib/bcel-5.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit.jar"/>
|
||||
<classpathentry kind="lib" path="hyperic_jni/lib/cpptasks.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="/Developer/Java/Ant/lib/ant.jar"/>
|
||||
<classpathentry kind="lib" path="lib/log4j.jar"/>
|
||||
<classpathentry kind="lib" path="sigar-bin/lib/sigar.jar"/>
|
||||
<classpathentry kind="output" path="build/classes"/>
|
||||
</classpath>
|
||||
|
|
Binary file not shown.
|
@ -39,7 +39,6 @@ public class Runner {
|
|||
private static final String JAR_EXT = ".jar";
|
||||
|
||||
static {
|
||||
wantedJars.put("bcel", Boolean.FALSE);
|
||||
wantedJars.put("junit", Boolean.FALSE);
|
||||
wantedJars.put("log4j", Boolean.FALSE);
|
||||
}
|
||||
|
|
|
@ -36,9 +36,8 @@ import org.hyperic.sigar.ProcStat;
|
|||
*
|
||||
* Example to display java processes only:<br>
|
||||
* <code>% java -jar sigar-bin/lib/sigar.jar Top State.Name.eq=java</code>
|
||||
*
|
||||
* @see org.hyperic.sigar.ptql.ProcessQueryBuilder
|
||||
*/
|
||||
|
||||
public class Top {
|
||||
private static final int SLEEP_TIME = 1000 * 5;
|
||||
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hyperic.sigar.SigarException;
|
||||
|
||||
public class PidFileQuery extends PidQuery {
|
||||
|
||||
File file;
|
||||
long modified = -1;
|
||||
|
||||
public PidFileQuery(String file) {
|
||||
this.file = new File(file);
|
||||
}
|
||||
|
||||
public long getPid()
|
||||
throws SigarException {
|
||||
|
||||
if (!file.exists()) {
|
||||
throw new SigarException(this.file + " does not exist");
|
||||
}
|
||||
|
||||
long lastMod = file.lastModified();
|
||||
if (lastMod == this.modified) {
|
||||
return this.pid;
|
||||
}
|
||||
|
||||
this.modified = lastMod;
|
||||
|
||||
String line;
|
||||
|
||||
try {
|
||||
BufferedReader in =
|
||||
new BufferedReader(new FileReader(this.file));
|
||||
while ((line = in.readLine()) != null) {
|
||||
line = line.trim();
|
||||
if (line.length() != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new SigarException(e.getMessage());
|
||||
} catch (IOException e) {
|
||||
throw new SigarException(e.getMessage());
|
||||
}
|
||||
|
||||
int len = line.length();
|
||||
StringBuffer number = new StringBuffer(len);
|
||||
char[] chars = line.toCharArray();
|
||||
for (int i=0; i<len; i++) {
|
||||
char c = chars[i];
|
||||
if (!Character.isDigit(c)) {
|
||||
break;
|
||||
}
|
||||
number.append(c);
|
||||
}
|
||||
|
||||
try {
|
||||
this.pid = Long.parseLong(number.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new SigarException("Not a number: " + line);
|
||||
}
|
||||
|
||||
return this.pid;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import org.hyperic.sigar.SigarException;
|
||||
import org.hyperic.sigar.SigarProxy;
|
||||
|
||||
public class PidQuery implements ProcessQuery {
|
||||
protected long pid;
|
||||
|
||||
protected PidQuery() { }
|
||||
|
||||
public PidQuery(long pid) {
|
||||
this.pid = pid;
|
||||
}
|
||||
|
||||
public PidQuery(String pid) {
|
||||
this.pid = Long.parseLong(pid);
|
||||
}
|
||||
|
||||
public long getPid()
|
||||
throws SigarException {
|
||||
|
||||
return this.pid;
|
||||
}
|
||||
|
||||
public boolean match(SigarProxy sigar, long pid)
|
||||
throws SigarException {
|
||||
|
||||
return pid == getPid();
|
||||
}
|
||||
}
|
|
@ -45,18 +45,16 @@ public class ProcessFinder {
|
|||
return findSingleProcess(processQuery);
|
||||
} catch (MalformedQueryException e) {
|
||||
throw new SigarException(e.getMessage());
|
||||
} catch (QueryLoadException e) {
|
||||
throw new SigarException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public long findSingleProcess(ProcessQuery query)
|
||||
throws SigarException, SigarNotImplementedException,
|
||||
MalformedQueryException {
|
||||
|
||||
if (query instanceof PidQuery) {
|
||||
return ((PidQuery)query).getPid();
|
||||
}
|
||||
//XXX bring back in another form
|
||||
//if (query instanceof PidQuery) {
|
||||
// return ((PidQuery)query).getPid();
|
||||
//}
|
||||
|
||||
int i, matches = 0;
|
||||
|
||||
|
@ -109,8 +107,6 @@ public class ProcessFinder {
|
|||
|
||||
try {
|
||||
return finder.find(ProcessQueryFactory.getInstance(query));
|
||||
} catch (QueryLoadException e) {
|
||||
throw new SigarException(e.getMessage());
|
||||
} catch (MalformedQueryException e) {
|
||||
throw new SigarException(e.getMessage());
|
||||
}
|
||||
|
@ -127,8 +123,6 @@ public class ProcessFinder {
|
|||
|
||||
try {
|
||||
return find(ProcessQueryFactory.getInstance(query));
|
||||
} catch (QueryLoadException e) {
|
||||
throw new SigarException(e.getMessage());
|
||||
} catch (MalformedQueryException e) {
|
||||
throw new SigarException(e.getMessage());
|
||||
}
|
||||
|
|
|
@ -1,880 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hyperic.sigar.NetFlags;
|
||||
import org.hyperic.sigar.SigarException;
|
||||
import org.hyperic.sigar.SigarProxy;
|
||||
|
||||
import org.apache.bcel.Constants;
|
||||
import org.apache.bcel.generic.BranchInstruction;
|
||||
import org.apache.bcel.generic.ClassGen;
|
||||
import org.apache.bcel.generic.ConstantPoolGen;
|
||||
import org.apache.bcel.generic.InstructionConstants;
|
||||
import org.apache.bcel.generic.InstructionFactory;
|
||||
import org.apache.bcel.generic.InstructionHandle;
|
||||
import org.apache.bcel.generic.InstructionList;
|
||||
import org.apache.bcel.generic.MethodGen;
|
||||
import org.apache.bcel.generic.ObjectType;
|
||||
import org.apache.bcel.generic.PUSH;
|
||||
import org.apache.bcel.generic.Type;
|
||||
|
||||
/**
|
||||
* Build a Process Query using a PTQL string.
|
||||
*
|
||||
* Queries must be in the following format:
|
||||
* <pre>
|
||||
* Class.Attribute.operator=value
|
||||
* </pre>
|
||||
* Where:
|
||||
* <ul>
|
||||
* <li> <b>Class</b> is the name of the Sigar class minus the Proc prefix.
|
||||
* <li> <b>Attribute</b> is an attribute of the given <b>Class</b>,
|
||||
* index into an array or key in a Map class.
|
||||
* <li> <b>operator</b> is one of the following for String values:
|
||||
* <ul>
|
||||
* <li> <b>eq</b> - Equal to <b>value</b>
|
||||
* <li> <b>ne</b> - Not Equal to <b>value</b>
|
||||
* <li> <b>ew</b> - Ends with <b>value</b>
|
||||
* <li> <b>sw</b> - Starts with <b>value</b>
|
||||
* <li> <b>ct</b> - Contains <b>value</b> (substring)
|
||||
* <li> <b>re</b> - Regular expression <b>value</b> matches
|
||||
* </ul>
|
||||
* <li> <b>operator</b> is one of the following for numeric values:
|
||||
* <ul>
|
||||
* <li> <b>eq</b> - Equal to <b>value</b>
|
||||
* <li> <b>ne</b> - Not Equal to <b>value</b>
|
||||
* <li> <b>gt</b> - Greater than <b>value</b>
|
||||
* <li> <b>ge</b> - Greater than or equal <b>value</b>
|
||||
* <li> <b>lt</b> - Less than <b>value</b>
|
||||
* <li> <b>le</b> - Less than or equal <b>value</b>
|
||||
* </ul>
|
||||
* </ul>
|
||||
* Multiple queries must delimited by a comma.
|
||||
* <p>
|
||||
* Examples can be found in the sigar-bin/lib/.sigar_shellrc file of
|
||||
* the Sigar distribution.
|
||||
*/
|
||||
public class ProcessQueryBuilder {
|
||||
|
||||
//set true during development to dump generated
|
||||
//.class files to disk.
|
||||
private static final boolean dumpClasses =
|
||||
"true".equals(System.getProperty("sigar.ptql.dumpClasses"));
|
||||
|
||||
private static int generation = 0;
|
||||
|
||||
private static final String SIGAR_PACKAGE =
|
||||
"org.hyperic.sigar.";
|
||||
|
||||
private static final String PROC_PREFIX =
|
||||
SIGAR_PACKAGE + "Proc";
|
||||
|
||||
private static final String PROXY_CLASS =
|
||||
SIGAR_PACKAGE + "SigarProxy";
|
||||
|
||||
private static final String PROXY_HELPER =
|
||||
SIGAR_PACKAGE + "ptql.ProcessQueryHelper";
|
||||
|
||||
private static final String GENERATION_PACKAGE =
|
||||
SIGAR_PACKAGE + "ptql.GENERATED.";
|
||||
|
||||
private static final String[] GENERATION_IMPL =
|
||||
new String[] { ProcessQuery.class.getName() };
|
||||
|
||||
public static final Class[] NOPARAM =
|
||||
new Class[] {};
|
||||
|
||||
static final char MOD_CLONE = 'C';
|
||||
static final char MOD_PARENT = 'P';
|
||||
static final char MOD_VALUE = 'V';
|
||||
|
||||
private static final HashMap INUMOPS;
|
||||
private static final HashMap LNUMOPS;
|
||||
private static final HashMap STROPS;
|
||||
|
||||
private static final HashMap IFMETHODS;
|
||||
|
||||
private InstructionFactory factory;
|
||||
private ConstantPoolGen pool;
|
||||
private ClassGen generator;
|
||||
private String className;
|
||||
|
||||
//ProcessQuery.match method impl
|
||||
private MethodGen query;
|
||||
//query instructions (match method body)
|
||||
private InstructionList qi = new InstructionList();
|
||||
//branches of query method
|
||||
private ArrayList branches = new ArrayList();
|
||||
|
||||
static final boolean COMPAT_1_4;
|
||||
|
||||
static {
|
||||
//long
|
||||
HashMap lnops = new HashMap();
|
||||
lnops.put("eq", new Short(Constants.IFNE));
|
||||
lnops.put("ne", new Short(Constants.IFEQ));
|
||||
lnops.put("gt", new Short(Constants.IFGE));
|
||||
lnops.put("ge", new Short(Constants.IFGT));
|
||||
lnops.put("lt", new Short(Constants.IFLE));
|
||||
lnops.put("le", new Short(Constants.IFLT));
|
||||
LNUMOPS = lnops;
|
||||
|
||||
//int
|
||||
HashMap inops = new HashMap();
|
||||
inops.put("eq", new Short(Constants.IF_ICMPNE));
|
||||
inops.put("ne", new Short(Constants.IF_ICMPEQ));
|
||||
inops.put("gt", new Short(Constants.IF_ICMPGE));
|
||||
inops.put("ge", new Short(Constants.IF_ICMPGT));
|
||||
inops.put("lt", new Short(Constants.IF_ICMPLE));
|
||||
inops.put("le", new Short(Constants.IF_ICMPLT));
|
||||
INUMOPS = inops;
|
||||
|
||||
HashMap sops = new HashMap();
|
||||
sops.put("ew", new StringOp("endsWith", Constants.IFEQ));
|
||||
sops.put("sw", new StringOp("startsWith", Constants.IFEQ));
|
||||
sops.put("eq", new StringOp("equals", Constants.IFEQ));
|
||||
sops.put("ne", new StringOp("equals", Constants.IFNE));
|
||||
sops.put("re", new StringOp("matches", Constants.IFEQ));
|
||||
sops.put("ct", new StringOp("indexOf", Constants.IF_ICMPEQ));
|
||||
STROPS = sops;
|
||||
|
||||
HashMap iftab = new HashMap();
|
||||
Method[] methods = SigarProxy.class.getMethods();
|
||||
|
||||
for (int i=0; i<methods.length; i++) {
|
||||
String name = methods[i].getName();
|
||||
|
||||
if (!name.startsWith("getProc")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class[] params = methods[i].getParameterTypes();
|
||||
|
||||
//getProcFoo(long pid)
|
||||
if (!((params.length == 1) &&
|
||||
(params[0] == Long.TYPE)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
iftab.put(name.substring(7), methods[i]);
|
||||
}
|
||||
IFMETHODS = iftab;
|
||||
|
||||
boolean isCompat;
|
||||
|
||||
try {
|
||||
Class.forName("java.net.SocketAddress");
|
||||
isCompat = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
isCompat = false;
|
||||
}
|
||||
|
||||
COMPAT_1_4 = isCompat;
|
||||
}
|
||||
|
||||
public ProcessQueryBuilder() {
|
||||
init();
|
||||
}
|
||||
|
||||
public static Map getMethods() {
|
||||
return IFMETHODS;
|
||||
}
|
||||
|
||||
public static Set getMethodOpNames(Method method) {
|
||||
if (method == null) {
|
||||
return STROPS.keySet();
|
||||
}
|
||||
|
||||
Class rtype = method.getReturnType();
|
||||
|
||||
if ((rtype == Character.TYPE) ||
|
||||
(rtype == Double.TYPE) ||
|
||||
(rtype == Integer.TYPE) ||
|
||||
(rtype == Long.TYPE))
|
||||
{
|
||||
return LNUMOPS.keySet();
|
||||
}
|
||||
|
||||
return STROPS.keySet();
|
||||
}
|
||||
|
||||
public static boolean isSigarClass(Class type) {
|
||||
return type.getName().startsWith(SIGAR_PACKAGE);
|
||||
}
|
||||
|
||||
class QueryOp {
|
||||
String op;
|
||||
int flags;
|
||||
boolean isParent = false;
|
||||
boolean isClone = false;
|
||||
boolean isValue = false;
|
||||
|
||||
public QueryOp(String val)
|
||||
throws MalformedQueryException {
|
||||
|
||||
int i=0;
|
||||
char c;
|
||||
while (Character.isUpperCase((c = val.charAt(i)))) {
|
||||
switch (c) {
|
||||
case MOD_CLONE:
|
||||
this.isClone = true;
|
||||
break;
|
||||
case MOD_PARENT:
|
||||
this.isParent = true;
|
||||
break;
|
||||
case MOD_VALUE:
|
||||
this.isValue = true;
|
||||
break;
|
||||
default:
|
||||
String msg = "Unsupported modifier: " + c;
|
||||
throw new MalformedQueryException(msg);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
this.op = val.substring(i);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
String name = genClassName();
|
||||
this.className = GENERATION_PACKAGE + name;
|
||||
|
||||
this.generator =
|
||||
new ClassGen(this.className,
|
||||
"java.lang.Object",
|
||||
className + ".java",
|
||||
Constants.ACC_PUBLIC|Constants.ACC_SUPER,
|
||||
GENERATION_IMPL);
|
||||
|
||||
this.pool = this.generator.getConstantPool();
|
||||
|
||||
this.factory = new InstructionFactory(this.generator,
|
||||
this.pool);
|
||||
|
||||
createConstructor();
|
||||
|
||||
this.query =
|
||||
new MethodGen(Constants.ACC_PUBLIC,
|
||||
Type.BOOLEAN,
|
||||
new Type[] { new ObjectType(PROXY_CLASS), Type.LONG },
|
||||
new String[] { "sigar", "pid" }, "match", getClassName(),
|
||||
this.qi, this.pool);
|
||||
}
|
||||
|
||||
//arg 1 passed to ProcessQuery.match
|
||||
private void loadSigarArg() {
|
||||
this.qi.append(InstructionFactory.createLoad(Type.OBJECT, 1));
|
||||
}
|
||||
|
||||
//arg 2 passed to ProcessQuery.match
|
||||
private void loadPidArg() {
|
||||
this.qi.append(InstructionFactory.createLoad(Type.LONG, 2));
|
||||
}
|
||||
|
||||
private static synchronized String genClassName() {
|
||||
return "PTQL" + generation++;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return this.className;
|
||||
}
|
||||
|
||||
private void createConstructor() {
|
||||
InstructionList il = new InstructionList();
|
||||
|
||||
MethodGen method =
|
||||
new MethodGen(Constants.ACC_PUBLIC,
|
||||
Type.VOID, Type.NO_ARGS,
|
||||
new String[] {}, "<init>",
|
||||
getClassName(),
|
||||
il, this.pool);
|
||||
|
||||
il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
|
||||
il.append(this.factory.createInvoke("java.lang.Object",
|
||||
"<init>",
|
||||
Type.VOID, Type.NO_ARGS,
|
||||
Constants.INVOKESPECIAL));
|
||||
|
||||
il.append(InstructionFactory.createReturn(Type.VOID));
|
||||
method.setMaxStack();
|
||||
method.setMaxLocals();
|
||||
this.generator.addMethod(method.getMethod());
|
||||
il.dispose();
|
||||
}
|
||||
|
||||
private void loadStandardArgs(QueryOp qop) {
|
||||
|
||||
if (qop.isParent) {
|
||||
loadSigarArg();
|
||||
}
|
||||
|
||||
loadSigarArg();
|
||||
loadPidArg();
|
||||
|
||||
if (!qop.isParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
//e.g. sigar.getProcState(pid).getName() is converted to:
|
||||
// sigar.getProcState(sigar.getProcState(pid).getPpid()).getName()
|
||||
final String procState = SIGAR_PACKAGE + "ProcState";
|
||||
|
||||
this.qi.append(this.factory.createInvoke(PROXY_CLASS,
|
||||
"getProcState",
|
||||
new ObjectType(procState),
|
||||
new Type[] { Type.LONG },
|
||||
Constants.INVOKEINTERFACE));
|
||||
|
||||
this.qi.append(this.factory.createInvoke(procState,
|
||||
"getPpid",
|
||||
Type.LONG, Type.NO_ARGS,
|
||||
Constants.INVOKEVIRTUAL));
|
||||
}
|
||||
|
||||
//e.g. sigar.getProcState(pid).getName()
|
||||
//attrClass == "State"
|
||||
//attr == "Name"
|
||||
//type == Type.STRING (return type)
|
||||
private void createStandardInvoker(String attrClass, String attr, Type type) {
|
||||
this.qi.append(this.factory.createInvoke(PROXY_CLASS,
|
||||
"getProc" + attrClass,
|
||||
new ObjectType(PROC_PREFIX + attrClass),
|
||||
new Type[] { Type.LONG },
|
||||
Constants.INVOKEINTERFACE));
|
||||
|
||||
this.qi.append(this.factory.createInvoke(PROC_PREFIX + attrClass,
|
||||
"get" + attr,
|
||||
type, Type.NO_ARGS,
|
||||
Constants.INVOKEVIRTUAL));
|
||||
}
|
||||
|
||||
private MalformedQueryException unsupportedOp(String name) {
|
||||
return new MalformedQueryException("Unsupported operator: " +
|
||||
name);
|
||||
}
|
||||
|
||||
private MalformedQueryException unsupportedMethod(String name) {
|
||||
return new MalformedQueryException("Unsupported method: " +
|
||||
name);
|
||||
}
|
||||
|
||||
private MalformedQueryException unsupportedAttribute(String name) {
|
||||
return new MalformedQueryException("Unsupported attribute: " +
|
||||
name);
|
||||
}
|
||||
|
||||
private StringOp getStringOp(String op)
|
||||
throws QueryLoadException,
|
||||
MalformedQueryException {
|
||||
|
||||
StringOp sop = (StringOp)STROPS.get(op);
|
||||
|
||||
if (sop == null) {
|
||||
throw unsupportedOp(op);
|
||||
}
|
||||
|
||||
if (!COMPAT_1_4) {
|
||||
if (op.equals("re")) {
|
||||
throw new QueryLoadException(op + " requires jdk 1.4+");
|
||||
}
|
||||
}
|
||||
|
||||
return sop;
|
||||
}
|
||||
|
||||
private void createStringInvoker(String op)
|
||||
throws QueryLoadException,
|
||||
MalformedQueryException {
|
||||
|
||||
StringOp sop = getStringOp(op);
|
||||
|
||||
this.qi.append(this.factory.createInvoke("java.lang.String", sop.name,
|
||||
sop.returnType, new Type[] { sop.type },
|
||||
Constants.INVOKEVIRTUAL));
|
||||
|
||||
if (op.equals("ct")) {
|
||||
this.qi.append(new PUSH(this.pool, -1));
|
||||
}
|
||||
|
||||
BranchInstruction branch =
|
||||
InstructionFactory.createBranchInstruction(sop.opcode, null);
|
||||
this.qi.append(branch);
|
||||
|
||||
this.branches.add(branch);
|
||||
}
|
||||
|
||||
//special case
|
||||
public void appendProcPortOp(String flags, String op,
|
||||
int protocol, long val)
|
||||
throws MalformedQueryException {
|
||||
|
||||
//XXX flags current unused; could be used to narrow search scope.
|
||||
QueryOp qop = new QueryOp(op);
|
||||
|
||||
loadSigarArg();
|
||||
|
||||
this.qi.append(new PUSH(this.pool, protocol));
|
||||
|
||||
this.qi.append(new PUSH(this.pool, val)); //port
|
||||
|
||||
this.qi.append(this.factory.createInvoke(PROXY_CLASS,
|
||||
"getProcPort",
|
||||
Type.LONG,
|
||||
new Type[] {
|
||||
Type.INT,
|
||||
Type.LONG
|
||||
},
|
||||
Constants.INVOKEINTERFACE));
|
||||
|
||||
loadPidArg();
|
||||
|
||||
this.qi.append(InstructionConstants.LCMP);
|
||||
|
||||
Short sop = (Short)LNUMOPS.get(qop.op);
|
||||
|
||||
if (sop == null) {
|
||||
throw unsupportedOp(qop.op);
|
||||
}
|
||||
|
||||
BranchInstruction branch =
|
||||
InstructionFactory.createBranchInstruction(sop.shortValue(), null);
|
||||
this.qi.append(branch);
|
||||
|
||||
this.branches.add(branch);
|
||||
}
|
||||
|
||||
//special case
|
||||
public void appendEnvOp(String key, String op, String val)
|
||||
throws QueryLoadException,
|
||||
MalformedQueryException {
|
||||
|
||||
QueryOp qop = new QueryOp(op);
|
||||
|
||||
loadStandardArgs(qop);
|
||||
|
||||
this.qi.append(new PUSH(this.pool, key));
|
||||
|
||||
this.qi.append(this.factory.createInvoke(PROXY_HELPER,
|
||||
"getProcEnv", Type.STRING,
|
||||
new Type[] {
|
||||
new ObjectType(PROXY_CLASS),
|
||||
Type.LONG, Type.STRING
|
||||
},
|
||||
Constants.INVOKESTATIC));
|
||||
|
||||
this.qi.append(new PUSH(this.pool, val));
|
||||
|
||||
createStringInvoker(qop.op);
|
||||
}
|
||||
|
||||
//special case
|
||||
public void appendArgsOp(int idx, String op, String val)
|
||||
throws QueryLoadException,
|
||||
MalformedQueryException {
|
||||
|
||||
QueryOp qop = new QueryOp(op);
|
||||
|
||||
loadStandardArgs(qop);
|
||||
|
||||
this.qi.append(new PUSH(this.pool, idx));
|
||||
|
||||
this.qi.append(this.factory.createInvoke(PROXY_HELPER,
|
||||
"getProcArg", Type.STRING,
|
||||
new Type[] {
|
||||
new ObjectType(PROXY_CLASS),
|
||||
Type.LONG, Type.INT
|
||||
},
|
||||
Constants.INVOKESTATIC));
|
||||
|
||||
this.qi.append(new PUSH(this.pool, val));
|
||||
|
||||
createStringInvoker(qop.op);
|
||||
}
|
||||
|
||||
public void appendArgsMatch(String op, String val)
|
||||
throws QueryLoadException,
|
||||
MalformedQueryException {
|
||||
|
||||
QueryOp qop = new QueryOp(op);
|
||||
|
||||
getStringOp(qop.op); //validate
|
||||
|
||||
loadStandardArgs(qop);
|
||||
|
||||
this.qi.append(new PUSH(this.pool, val));
|
||||
this.qi.append(new PUSH(this.pool, qop.op));
|
||||
|
||||
this.qi.append(this.factory.createInvoke(PROXY_HELPER,
|
||||
"argsMatch", Type.BOOLEAN,
|
||||
new Type[] {
|
||||
new ObjectType(PROXY_CLASS),
|
||||
Type.LONG,
|
||||
Type.STRING,
|
||||
Type.STRING
|
||||
},
|
||||
Constants.INVOKESTATIC));
|
||||
|
||||
BranchInstruction branch =
|
||||
InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
|
||||
this.qi.append(branch);
|
||||
|
||||
this.branches.add(branch);
|
||||
}
|
||||
|
||||
public void appendStringOp(String attrClass, String attr,
|
||||
String op, String val)
|
||||
throws QueryLoadException,
|
||||
MalformedQueryException {
|
||||
|
||||
QueryOp qop = new QueryOp(op);
|
||||
|
||||
loadStandardArgs(qop);
|
||||
|
||||
createStandardInvoker(attrClass, attr, Type.STRING);
|
||||
|
||||
if (qop.isValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (qop.isClone) {
|
||||
append(val, null);
|
||||
}
|
||||
else {
|
||||
this.qi.append(new PUSH(this.pool, val));
|
||||
}
|
||||
|
||||
createStringInvoker(qop.op);
|
||||
}
|
||||
|
||||
public void appendNumberOp(String attrClass, String attr,
|
||||
String op, int val)
|
||||
throws MalformedQueryException {
|
||||
|
||||
appendNumberOp(attrClass, attr, op, Type.INT,
|
||||
0, 0.0, val);
|
||||
}
|
||||
|
||||
public void appendNumberOp(String attrClass, String attr,
|
||||
String op, long val)
|
||||
throws MalformedQueryException {
|
||||
|
||||
appendNumberOp(attrClass, attr, op, Type.LONG,
|
||||
val, 0.0, 0);
|
||||
}
|
||||
|
||||
public void appendNumberOp(String attrClass, String attr,
|
||||
String op, double val)
|
||||
throws MalformedQueryException {
|
||||
|
||||
appendNumberOp(attrClass, attr, op, Type.DOUBLE,
|
||||
0, val, 0);
|
||||
}
|
||||
|
||||
private void appendNumberOp(String attrClass, String attr,
|
||||
String op, Type type,
|
||||
long val, double dval, int ival)
|
||||
throws MalformedQueryException {
|
||||
|
||||
HashMap nops;
|
||||
|
||||
if ((type == Type.INT) ||
|
||||
(type == Type.CHAR))
|
||||
{
|
||||
nops = INUMOPS;
|
||||
this.qi.append(new PUSH(this.pool, ival));
|
||||
}
|
||||
else if (type == Type.DOUBLE) {
|
||||
nops = LNUMOPS;
|
||||
this.qi.append(new PUSH(this.pool, dval));
|
||||
}
|
||||
else {
|
||||
nops = LNUMOPS;
|
||||
this.qi.append(new PUSH(this.pool, val));
|
||||
}
|
||||
|
||||
QueryOp qop = new QueryOp(op);
|
||||
|
||||
loadStandardArgs(qop);
|
||||
|
||||
createStandardInvoker(attrClass, attr, type);
|
||||
|
||||
Short sop = (Short)nops.get(qop.op);
|
||||
|
||||
if (sop == null) {
|
||||
throw unsupportedOp(qop.op);
|
||||
}
|
||||
|
||||
if (type == Type.LONG) {
|
||||
this.qi.append(InstructionConstants.LCMP);
|
||||
}
|
||||
else if (type == Type.DOUBLE) {
|
||||
this.qi.append(InstructionConstants.DCMPL);
|
||||
}
|
||||
|
||||
BranchInstruction branch =
|
||||
InstructionFactory.createBranchInstruction(sop.shortValue(), null);
|
||||
this.qi.append(branch);
|
||||
|
||||
this.branches.add(branch);
|
||||
}
|
||||
|
||||
private void appendPidOp(String op, String val)
|
||||
throws MalformedQueryException {
|
||||
|
||||
long longVal;
|
||||
HashMap nops = LNUMOPS;
|
||||
|
||||
if (val.equals("$$")) {
|
||||
loadSigarArg();
|
||||
|
||||
this.qi.append(this.factory.createInvoke(PROXY_CLASS,
|
||||
"getPid",
|
||||
Type.LONG, Type.NO_ARGS,
|
||||
Constants.INVOKEINTERFACE));
|
||||
}
|
||||
else {
|
||||
try {
|
||||
longVal = Long.parseLong(val);
|
||||
} catch (NumberFormatException e) {
|
||||
String msg = "Pid value '" + val + "' is not a number";
|
||||
throw new MalformedQueryException(msg);
|
||||
}
|
||||
|
||||
this.qi.append(new PUSH(this.pool, longVal));
|
||||
}
|
||||
|
||||
loadPidArg();
|
||||
|
||||
QueryOp qop = new QueryOp(op);
|
||||
|
||||
Short sop = (Short)nops.get(qop.op);
|
||||
|
||||
if (sop == null) {
|
||||
throw unsupportedOp(qop.op);
|
||||
}
|
||||
|
||||
this.qi.append(InstructionConstants.LCMP);
|
||||
|
||||
BranchInstruction branch =
|
||||
InstructionFactory.createBranchInstruction(sop.shortValue(), null);
|
||||
this.qi.append(branch);
|
||||
|
||||
this.branches.add(branch);
|
||||
}
|
||||
|
||||
public void append(String branch, String val)
|
||||
throws QueryLoadException,
|
||||
MalformedQueryException {
|
||||
|
||||
QueryBranch qb = new QueryBranch(branch);
|
||||
|
||||
String attrClass=qb.attrClass, attr=qb.attr, op=qb.op;
|
||||
|
||||
if (attrClass.equals("Env")) {
|
||||
appendEnvOp(attr, op, val);
|
||||
}
|
||||
else if (attrClass.equals("Args")) {
|
||||
if (attr.equals("*")) {
|
||||
//run op against all args
|
||||
appendArgsMatch(op, val);
|
||||
}
|
||||
else {
|
||||
int idx;
|
||||
try {
|
||||
idx = Integer.parseInt(attr);
|
||||
} catch (NumberFormatException e) {
|
||||
String msg = "Array index '" + attr + "' is not a number";
|
||||
throw new MalformedQueryException(msg);
|
||||
}
|
||||
appendArgsOp(idx, op, val);
|
||||
}
|
||||
}
|
||||
else if (attrClass.equals("Port")) {
|
||||
int protocol;
|
||||
long port;
|
||||
try {
|
||||
port = Long.parseLong(val);
|
||||
} catch (NumberFormatException e) {
|
||||
String msg = "Port value '" + val + "' is not a number";
|
||||
throw new MalformedQueryException(msg);
|
||||
}
|
||||
try {
|
||||
protocol = NetFlags.getConnectionProtocol(attr);
|
||||
} catch (SigarException e) {
|
||||
throw new MalformedQueryException(e.getMessage());
|
||||
}
|
||||
|
||||
appendProcPortOp(attr, op, protocol, port);
|
||||
}
|
||||
else if (attrClass.equals("Pid")) {
|
||||
appendPidOp(op, val);
|
||||
}
|
||||
else {
|
||||
Method method = (Method)IFMETHODS.get(attrClass);
|
||||
|
||||
if (method == null) {
|
||||
throw unsupportedMethod(attrClass);
|
||||
}
|
||||
|
||||
Class subtype = method.getReturnType();
|
||||
boolean isStringType = false;
|
||||
|
||||
if (isSigarClass(subtype)) {
|
||||
try {
|
||||
method = subtype.getMethod("get" + attr,
|
||||
NOPARAM);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw unsupportedAttribute(attr);
|
||||
}
|
||||
|
||||
if (method.getReturnType() == String.class) {
|
||||
isStringType = true;
|
||||
}
|
||||
else if (method.getReturnType() == Character.TYPE) {
|
||||
if (val.length() != 1) {
|
||||
String msg = val + " is not a char";
|
||||
throw new MalformedQueryException(msg);
|
||||
}
|
||||
|
||||
int c = (int)val.charAt(0);
|
||||
appendNumberOp(attrClass, attr, op, Type.CHAR,
|
||||
0, 0.0, c);
|
||||
return;
|
||||
}
|
||||
else if (method.getReturnType() == Double.TYPE) {
|
||||
try {
|
||||
double doubleVal = Double.parseDouble(val);
|
||||
appendNumberOp(attrClass, attr, op, doubleVal);
|
||||
return;
|
||||
} catch (NumberFormatException e) {
|
||||
String msg = val + " is not a double";
|
||||
throw new MalformedQueryException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
isStringType = true;
|
||||
}
|
||||
|
||||
if (!isStringType && Character.isDigit(val.charAt(0))) {
|
||||
try {
|
||||
long longVal = Long.parseLong(val);
|
||||
appendNumberOp(attrClass, attr, op, longVal);
|
||||
return;
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
appendStringOp(attrClass, attr, op, val);
|
||||
}
|
||||
}
|
||||
|
||||
String addModifier(String key, char modifier)
|
||||
throws MalformedQueryException {
|
||||
|
||||
int ix;
|
||||
if ((ix = key.lastIndexOf(".")) < 0) {
|
||||
throw new MalformedQueryException();
|
||||
}
|
||||
|
||||
return key.substring(0, ix+1) + modifier +
|
||||
key.substring(ix+1, key.length());
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
this.qi.append(new PUSH(this.pool, 1));
|
||||
|
||||
BranchInstruction gotoBranch =
|
||||
InstructionFactory.createBranchInstruction(Constants.GOTO, null);
|
||||
|
||||
this.qi.append(gotoBranch);
|
||||
|
||||
InstructionHandle target =
|
||||
this.qi.append(new PUSH(this.pool, 0));
|
||||
|
||||
InstructionHandle retval =
|
||||
this.qi.append(InstructionFactory.createReturn(Type.INT));
|
||||
|
||||
for (int i=0; i<this.branches.size(); i++) {
|
||||
BranchInstruction branch =
|
||||
(BranchInstruction)this.branches.get(i);
|
||||
branch.setTarget(target);
|
||||
}
|
||||
|
||||
gotoBranch.setTarget(retval);
|
||||
|
||||
this.query.setMaxStack();
|
||||
this.query.setMaxLocals();
|
||||
this.generator.addMethod(this.query.getMethod());
|
||||
this.qi.dispose();
|
||||
}
|
||||
|
||||
public ProcessQuery load()
|
||||
throws QueryLoadException {
|
||||
|
||||
if (dumpClasses) {
|
||||
try {
|
||||
FileOutputStream os =
|
||||
new FileOutputStream(getClassName() + ".class");
|
||||
dump(os);
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
byte[] bytecode = this.generator.getJavaClass().getBytes();
|
||||
ClassLoader parent = this.getClass().getClassLoader();
|
||||
ClassLoader cl = new ProcessQueryClassLoader(parent, bytecode);
|
||||
Class genclass;
|
||||
|
||||
try {
|
||||
genclass = cl.loadClass(getClassName());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new QueryLoadException("ClassNotFoundException: " +
|
||||
e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
return (ProcessQuery)genclass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new QueryLoadException("InstantiationException: " +
|
||||
e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new QueryLoadException("IllegalAccessException: " +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(OutputStream os) throws IOException {
|
||||
this.generator.getJavaClass().dump(os);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
class ProcessQueryClassLoader extends ClassLoader {
|
||||
private byte[] bytecode;
|
||||
|
||||
ProcessQueryClassLoader(ClassLoader parent, byte[] bytecode) {
|
||||
super(parent);
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
public Class findClass(String name) throws ClassNotFoundException {
|
||||
try {
|
||||
return defineClass(name, this.bytecode, 0, this.bytecode.length);
|
||||
} catch (ClassFormatError e) {
|
||||
throw new ClassNotFoundException("Class Format Error", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,131 +18,18 @@
|
|||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.hyperic.sigar.Sigar;
|
||||
import org.hyperic.sigar.SigarException;
|
||||
import org.hyperic.sigar.util.ReferenceMap;
|
||||
|
||||
public class ProcessQueryFactory implements Comparator {
|
||||
|
||||
//for testing until native port is completed
|
||||
private static final boolean useNative =
|
||||
"true".equals(System.getProperty("sigar.ptql.native"));
|
||||
public class ProcessQueryFactory {
|
||||
|
||||
private static Map cache =
|
||||
ReferenceMap.synchronizedMap();
|
||||
|
||||
public ProcessQueryFactory() {}
|
||||
|
||||
//sort what will become instruction branches.
|
||||
//so the cheapest are executed first.
|
||||
private int getOrder(String s) {
|
||||
if (s.startsWith("Port.")) {
|
||||
return 11;
|
||||
}
|
||||
else if (s.startsWith("Env.")) {
|
||||
return 10;
|
||||
}
|
||||
else if (s.startsWith("Args.")) {
|
||||
return 9;
|
||||
}
|
||||
else if (s.startsWith("Exe.")) {
|
||||
return 8;
|
||||
}
|
||||
else if (s.startsWith("State.")) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int compare(Object o1, Object o2) {
|
||||
|
||||
return getOrder((String)o1) -
|
||||
getOrder((String)o2);
|
||||
}
|
||||
|
||||
public ProcessQuery prepare(QueryBranchMap map)
|
||||
throws MalformedQueryException,
|
||||
QueryLoadException {
|
||||
|
||||
ProcessQueryBuilder builder = new ProcessQueryBuilder();
|
||||
|
||||
String[] keys =
|
||||
(String[])map.keySet().toArray(new String[0]);
|
||||
|
||||
Arrays.sort(keys, this);
|
||||
|
||||
for (int i=0; i<keys.length; i++) {
|
||||
String key = keys[i];
|
||||
String val = (String)map.get(key);
|
||||
|
||||
if (val.charAt(0) == '$') {
|
||||
String var = val.substring(1);
|
||||
|
||||
try {
|
||||
int ix = Integer.parseInt(var);
|
||||
//$1..n references
|
||||
ix--;
|
||||
if ((ix < 0) || (ix >= map.branches.size())) {
|
||||
String msg = "Variable out of range " + var;
|
||||
throw new MalformedQueryException(msg);
|
||||
}
|
||||
|
||||
var = (String)map.branches.get(ix);
|
||||
var = builder.addModifier(var,
|
||||
ProcessQueryBuilder.MOD_VALUE);
|
||||
key = builder.addModifier(key,
|
||||
ProcessQueryBuilder.MOD_CLONE);
|
||||
} catch (NumberFormatException e) {
|
||||
var = System.getProperty(var, val);
|
||||
}
|
||||
|
||||
val = var;
|
||||
}
|
||||
|
||||
builder.append(key, val);
|
||||
}
|
||||
|
||||
builder.finish();
|
||||
|
||||
return builder.load();
|
||||
}
|
||||
|
||||
private static ProcessQuery getPidInstance(String query)
|
||||
throws MalformedQueryException {
|
||||
|
||||
if (query.indexOf(",") > 0) {
|
||||
throw new MalformedQueryException("Invalid Pid query");
|
||||
}
|
||||
|
||||
String[] vals = QueryBranch.split(query);
|
||||
|
||||
QueryBranch branch = new QueryBranch(vals[0]);
|
||||
String val = vals[1];
|
||||
|
||||
if (!branch.op.equals("eq")) {
|
||||
throw new MalformedQueryException("Invalid Pid operator");
|
||||
}
|
||||
|
||||
if (branch.attr.equals("PidFile")) {
|
||||
return new PidFileQuery(val);
|
||||
}
|
||||
else if (branch.attr.equals("Service")) {
|
||||
return new WindowsServiceQuery(val);
|
||||
}
|
||||
|
||||
throw new MalformedQueryException("Unsupported method: " +
|
||||
branch.attr);
|
||||
}
|
||||
|
||||
public static ProcessQuery getInstance(String query)
|
||||
throws MalformedQueryException,
|
||||
QueryLoadException {
|
||||
throws MalformedQueryException {
|
||||
|
||||
if (query == null) {
|
||||
throw new MalformedQueryException("null query");
|
||||
|
@ -158,36 +45,9 @@ public class ProcessQueryFactory implements Comparator {
|
|||
return pQuery;
|
||||
}
|
||||
|
||||
if (useNative) {
|
||||
pQuery = new SigarProcessQuery();
|
||||
((SigarProcessQuery)pQuery).create(query);
|
||||
cache.put(query, pQuery);
|
||||
return pQuery;
|
||||
}
|
||||
|
||||
if (query.startsWith("Pid.PidFile.") ||
|
||||
query.startsWith("Pid.Service."))
|
||||
{
|
||||
pQuery = getPidInstance(query);
|
||||
cache.put(query, pQuery);
|
||||
return pQuery;
|
||||
}
|
||||
|
||||
QueryBranchMap queries = new QueryBranchMap();
|
||||
StringTokenizer st = new StringTokenizer(query, ",");
|
||||
|
||||
while (st.hasMoreTokens()) {
|
||||
String[] vals = QueryBranch.split(st.nextToken());
|
||||
|
||||
queries.put(vals[0], vals[1]);
|
||||
}
|
||||
|
||||
ProcessQueryFactory factory = new ProcessQueryFactory();
|
||||
|
||||
pQuery = factory.prepare(queries);
|
||||
|
||||
cache.put(query, pQuery);
|
||||
|
||||
return pQuery;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.hyperic.sigar.SigarException;
|
||||
import org.hyperic.sigar.SigarNotImplementedException;
|
||||
import org.hyperic.sigar.SigarProxy;
|
||||
|
||||
public class ProcessQueryHelper {
|
||||
|
||||
static HashMap stringMatchers = new HashMap();
|
||||
|
||||
static {
|
||||
stringMatchers.put("eq", new StringEqMatcher());
|
||||
stringMatchers.put("ne", new StringNeMatcher());
|
||||
stringMatchers.put("sw", new StringSwMatcher());
|
||||
stringMatchers.put("ew", new StringEwMatcher());
|
||||
stringMatchers.put("re", new StringReMatcher());
|
||||
stringMatchers.put("ct", new StringCtMatcher());
|
||||
}
|
||||
|
||||
//avoid NPE if key does not exist.
|
||||
public static String getProcEnv(SigarProxy proxy, long pid, String key)
|
||||
throws SigarException, SigarNotImplementedException {
|
||||
|
||||
Map vars;
|
||||
|
||||
try {
|
||||
vars = proxy.getProcEnv(pid);
|
||||
} catch (SigarNotImplementedException e) {
|
||||
throw e;
|
||||
} catch (SigarException e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String val = (String)vars.get(key);
|
||||
|
||||
if (val == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
//avoid ArrayOutOfBoundsException
|
||||
public static String getProcArg(SigarProxy proxy, long pid, int num)
|
||||
throws SigarException, SigarNotImplementedException {
|
||||
|
||||
String[] args;
|
||||
|
||||
try {
|
||||
args = proxy.getProcArgs(pid);
|
||||
} catch (SigarNotImplementedException e) {
|
||||
throw e;
|
||||
} catch (SigarException e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
//e.g. find last element of args: Args.-1.eq=weblogic.Server
|
||||
if (num < 0) {
|
||||
num += args.length;
|
||||
}
|
||||
|
||||
if ((num >= args.length) ||
|
||||
(num < 0)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return args[num];
|
||||
}
|
||||
|
||||
public interface StringMatcher {
|
||||
public boolean match(String left, String right);
|
||||
}
|
||||
|
||||
static class StringEqMatcher implements StringMatcher {
|
||||
public boolean match(String left, String right) {
|
||||
return left.equals(right);
|
||||
}
|
||||
}
|
||||
|
||||
static class StringNeMatcher implements StringMatcher {
|
||||
public boolean match(String left, String right) {
|
||||
return !left.equals(right);
|
||||
}
|
||||
}
|
||||
|
||||
static class StringEwMatcher implements StringMatcher {
|
||||
public boolean match(String left, String right) {
|
||||
return left.endsWith(right);
|
||||
}
|
||||
}
|
||||
|
||||
static class StringSwMatcher implements StringMatcher {
|
||||
public boolean match(String left, String right) {
|
||||
return left.startsWith(right);
|
||||
}
|
||||
}
|
||||
|
||||
static class StringCtMatcher implements StringMatcher {
|
||||
public boolean match(String left, String right) {
|
||||
return left.indexOf(right) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
static class StringReMatcher implements StringMatcher {
|
||||
public boolean match(String left, String right) {
|
||||
return StringPattern.matches(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean argsMatch(SigarProxy proxy, long pid,
|
||||
String value, String op)
|
||||
throws SigarException, SigarNotImplementedException {
|
||||
|
||||
String[] args = proxy.getProcArgs(pid);
|
||||
|
||||
StringMatcher matcher =
|
||||
(StringMatcher)stringMatchers.get(op);
|
||||
|
||||
for (int i=0; i<args.length; i++) {
|
||||
if (matcher.match(args[i], value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
class QueryBranch {
|
||||
String attrClass;
|
||||
String attr;
|
||||
String op;
|
||||
|
||||
QueryBranch(String query)
|
||||
throws MalformedQueryException {
|
||||
|
||||
StringTokenizer st = new StringTokenizer(query, ".");
|
||||
|
||||
try {
|
||||
this.attrClass = st.nextToken();
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new MalformedQueryException("Empty query");
|
||||
}
|
||||
|
||||
try {
|
||||
this.attr = st.nextToken();
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new MalformedQueryException("Missing attribute");
|
||||
}
|
||||
|
||||
try {
|
||||
this.op = st.nextToken();
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new MalformedQueryException("Missing operator");
|
||||
}
|
||||
}
|
||||
|
||||
static String[] split(String query)
|
||||
throws MalformedQueryException {
|
||||
|
||||
String[] vals = new String[2];
|
||||
|
||||
int ix = query.indexOf('=');
|
||||
|
||||
if (ix < 0) {
|
||||
throw new MalformedQueryException("Missing '='");
|
||||
}
|
||||
|
||||
vals[0] = query.substring(0, ix);
|
||||
vals[1] = query.substring(ix+1, query.length());
|
||||
|
||||
return vals;
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class QueryBranchMap extends HashMap {
|
||||
|
||||
ArrayList branches = new ArrayList();
|
||||
|
||||
public Object put(Object key, Object value) {
|
||||
branches.add(key);
|
||||
return super.put(key, value);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
/**
|
||||
* Exception for process queries which were
|
||||
* parsed ok but whos class generation failed.
|
||||
*/
|
||||
public class QueryLoadException extends Exception {
|
||||
|
||||
public QueryLoadException() {
|
||||
}
|
||||
|
||||
public QueryLoadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import org.apache.bcel.generic.Type;
|
||||
|
||||
class StringOp {
|
||||
String name;
|
||||
short opcode;
|
||||
Type type = Type.STRING;
|
||||
Type returnType = Type.BOOLEAN;
|
||||
|
||||
StringOp(String name, short opcode) {
|
||||
this.name = name;
|
||||
this.opcode = opcode;
|
||||
if (name.equals("equals")) {
|
||||
this.type = Type.OBJECT;
|
||||
}
|
||||
else if (name.equals("indexOf")) {
|
||||
this.returnType = Type.INT;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
||||
* This file is part of SIGAR.
|
||||
*
|
||||
* SIGAR is free software; you can redistribute it and/or modify
|
||||
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package org.hyperic.sigar.ptql;
|
||||
|
||||
import org.hyperic.sigar.Sigar;
|
||||
import org.hyperic.sigar.SigarProxy;
|
||||
import org.hyperic.sigar.SigarException;
|
||||
|
||||
public class WindowsServiceQuery implements ProcessQuery {
|
||||
|
||||
private String name;
|
||||
|
||||
public WindowsServiceQuery(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean match(SigarProxy sigar, long pid)
|
||||
throws SigarException {
|
||||
|
||||
return pid == sigar.getServicePid(this.name);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Sigar sigar = new Sigar(); //load the .dll
|
||||
System.out.println(sigar.getServicePid(args[0]));
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@ import org.hyperic.sigar.ptql.ProcessQuery;
|
|||
import org.hyperic.sigar.ptql.ProcessQueryFactory;
|
||||
import org.hyperic.sigar.ptql.ProcessFinder;
|
||||
import org.hyperic.sigar.ptql.MalformedQueryException;
|
||||
import org.hyperic.sigar.ptql.QueryLoadException;
|
||||
|
||||
public class TestPTQL extends SigarTestCase {
|
||||
|
||||
|
@ -101,16 +100,12 @@ public class TestPTQL extends SigarTestCase {
|
|||
//"Pid.Service.ne=Eventlog",
|
||||
};
|
||||
|
||||
private static final String[] LOAD_FAIL_QUERIES = {
|
||||
};
|
||||
|
||||
public TestPTQL(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
private int runQuery(SigarProxy proxy, String qs)
|
||||
throws MalformedQueryException,
|
||||
QueryLoadException,
|
||||
SigarException {
|
||||
|
||||
ProcessQuery query;
|
||||
|
@ -169,19 +164,6 @@ public class TestPTQL extends SigarTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
private void testLoadFailure(SigarProxy proxy) throws Exception {
|
||||
for (int i=0; i<LOAD_FAIL_QUERIES.length; i++) {
|
||||
String qs = LOAD_FAIL_QUERIES[i];
|
||||
try {
|
||||
runQuery(proxy, qs);
|
||||
fail(qs + " did not throw QueryLoadException");
|
||||
} catch (QueryLoadException e) {
|
||||
traceln(qs + ": " + e.getMessage());
|
||||
assertTrue(qs + " QueryLoad", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testCreate() throws Exception {
|
||||
SigarProxy proxy =
|
||||
SigarProxyCache.newInstance(getSigar());
|
||||
|
@ -193,7 +175,6 @@ public class TestPTQL extends SigarTestCase {
|
|||
}
|
||||
|
||||
testMalformed(proxy);
|
||||
testLoadFailure(proxy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue