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);
 | 
			
		||||
 | 
			
		||||
        pQuery = new SigarProcessQuery();
 | 
			
		||||
        ((SigarProcessQuery)pQuery).create(query);
 | 
			
		||||
        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
	
	Block a user