incubator-flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aha...@apache.org
Subject svn commit: r1333232 [24/34] - in /incubator/flex/trunk: ./ frameworks/tests/ frameworks/tests/basicTests/ frameworks/tests/basicTests/dmv/ frameworks/tests/basicTests/dmv/scripts/ frameworks/tests/basicTests/dmv/views/ frameworks/tests/basicTests/fxg/...
Date Wed, 02 May 2012 22:45:08 GMT
Added: incubator/flex/trunk/mustella/java/src/utils/CompcUtils.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/java/src/utils/CompcUtils.java?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/java/src/utils/CompcUtils.java (added)
+++ incubator/flex/trunk/mustella/java/src/utils/CompcUtils.java Wed May  2 22:44:38 2012
@@ -0,0 +1,395 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.StringTokenizer;
+import java.util.List;
+import java.util.Vector;
+import java.util.Iterator;
+
+import utils.FileUtils;
+import org.xml.sax.SAXException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+public class CompcUtils {
+    private String compc;
+    private String dir;
+    private long lastRunTime;
+    private RuntimeExecHelper reh;
+    private String execArgs[];
+    boolean printOut = false;
+    private String configfileIndicator1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+    private String configfileIndicator2 = "<flex-config xmlns=\"http://www.adobe.com/2006/flex-config\">";
+    private Vector swcs;
+    private boolean bConfigFileArgs = false;
+
+    private void debug(String msg) {
+        if (System.getProperty("debug") != null && System.getProperty("debug").equals("true")) {
+            System.out.println(msg);
+        }
+    }
+
+    //read args from system property = compc.args
+    public void compile() throws Exception {
+        String strArgs = System.getProperty("compc.args");
+        if (strArgs != null && !strArgs.equals("")) {
+            debug("got compc args from System property - compc.args = " + strArgs);
+            compile(strArgs);
+        } else {
+            throw new Exception("compc args from System property - compc.args are empty!");
+        }
+    }
+
+
+    public void compile(String args) throws Exception {
+        if (!args.equals("")) {
+            String[] aArgs;
+            StringTokenizer stok = new StringTokenizer(args, " ");
+            String[] tmp = new String[stok.countTokens()];
+            int count = 0;
+            while (stok.hasMoreTokens()) {
+                tmp[count] = stok.nextToken();
+                count++;
+            }
+            aArgs = tmp;
+            compile(aArgs);
+        } else {
+            throw new Exception("compc args are empty!");
+        }
+
+    }
+
+    //read args from file
+    public void compile(File argFile) throws Exception {
+        if (argFile.exists()) {
+            debug("reading compc args from file: " + argFile.getAbsolutePath());
+            // determine if arg file is a config file or lists of commandline args
+            List args = FileUtils.readLines(argFile.getAbsolutePath());
+            if (args.size() == 0) {
+                throw new Exception("compc args file " + argFile.getAbsolutePath() + " is empty!");
+            }
+
+            String frameworks = FileUtils.normalizeDir(System.getProperty("frameworks", "."));
+            String basedir=FileUtils.normalizeDir(System.getProperty("basedir"));
+            String mxunitdir=basedir+"/sdk/testsuites/mxunit";
+
+            try {
+                // if 1st 2 lines of argFile indicate that it is an xml config file, make compc args use the -config=argFile
+                if (((String) args.get(0)).trim().equalsIgnoreCase(configfileIndicator1) && ((String) args.get(1)).trim().equalsIgnoreCase((configfileIndicator2))) {
+                    args = new Vector();
+                    args.add("--load-config " + argFile.getAbsolutePath());
+                    bConfigFileArgs = true;
+                }
+            } catch (Exception e) {
+                //must only have 1 line so do nothing
+            }
+            Iterator it = args.iterator();
+            while (it.hasNext()) {
+                compile((String) it.next() + " +frameworks-dir " + frameworks + " +mxunit-dir " + mxunitdir);
+            }
+        } else {
+            throw new Exception("compc args file " + argFile.getAbsolutePath() + " does not exisit!");
+        }
+
+    }
+
+    //given an mxml Testfile,
+    //  if file with same name, but extension=compc exists, return that file
+    //  if file with same name as parent folder and extension=compc exists, return that file
+    public File getCompcArgFile(String mxmlTest) throws Exception {
+
+        return getArgFile(mxmlTest, "compc");
+    }
+
+    public File getRSLArgFile(String mxmlTest) throws Exception {
+        return getArgFile(mxmlTest, "rsl");
+    }
+
+    private File getArgFile(String mxmlTest, String extension) throws Exception {
+        //see if there is a .extension file in the folder with the same name as the folder
+        String folderpath = new File(mxmlTest).getParent();
+        String foldername = new File(folderpath).getName();
+        String folderBasedArgs = folderpath + File.separator + foldername + "." + extension;
+        //if file with same name as mxml, but extension=extension exists use it for args
+        String fileBasedArgs = mxmlTest.substring(0, mxmlTest.length() - 4) + extension;
+        File argFile = null;
+
+        if (new File(fileBasedArgs).exists()) {
+            debug("fileBasedArgs=" + fileBasedArgs + " exists.  Reading args.");
+            argFile = new File(fileBasedArgs);
+        } else if (new File(folderBasedArgs).exists()) {
+            debug("folderBasedArgs=" + folderBasedArgs + " exists.  Reading args.");
+            argFile = new File(folderBasedArgs);
+        } else {
+            throw new Exception(extension + " argFile does not exist");
+        }
+        return argFile;
+    }
+
+
+    public void compile(String[] args) throws Exception {
+        compc(args);
+    }
+
+    private void compc(String[] args) throws Exception {
+        //compcdir and compcexe must be specified as system properties!
+        String compcdir = System.getProperty("compcdir");
+        String compcexe = System.getProperty("compcexe");
+        compc = FileUtils.normalizeDirOS(compcdir + File.separator + compcexe);
+        debug("compcdir=" + compcdir);
+        debug("compcexe=" + compcexe);
+        debug("compc=" + compc);
+
+        if (compc == null || new File(compc).isFile() == false) {
+            throw new Exception("compc compiler not set correctly, compc=" + compc);
+        }
+
+        // frameworks must be specified as system property.
+        // This will be used later on as the working directory for compilation
+        String frameworks = FileUtils.normalizeDir(System.getProperty("frameworks"));
+        if (frameworks == null || new File(frameworks).isDirectory() == false) {
+            throw new Exception("frameworks not set correctly, frameworks=" + frameworks);
+        }
+        debug("frameworks=" + frameworks);
+        if (dir == null)
+        	dir = frameworks;
+
+        execArgs = new String[args.length + 1];
+        execArgs[0] = compc;
+        for (int i = 0; i < args.length; i++) {
+            execArgs[i + 1] = args[i];
+        }
+
+        debug("cd " + dir);
+        System.out.println(StringUtils.arrayToString(execArgs));
+
+        int timeout = 300;
+        try {
+            timeout = Integer.parseInt(System.getProperty("compc.timeout"));
+        } catch (Exception e) {
+        }
+
+        swcs = new Vector();
+
+        //delete output swc if it already exists and add swc to list of swcs generated
+        // uh...this doesn't really work if swc is relative..
+        String swcname=getSwc(execArgs);
+        /*
+        debug(">>>>> deleting old swc if it exists: " + swcname);
+        if (!swcname.endsWith(".swc")){
+            debug(">>>>> swc is dir so emptying dir");
+            File f = new File(swcname);
+            if (f.isDirectory()){
+                File[] fa=f.listFiles();
+                for (int x=0;x<fa.length;x++){
+                    debug(">>>>> deleting: " + fa[x].getAbsolutePath());
+                    fa[x].delete();
+                }
+             }
+        }
+        */
+        utils.FileUtils.deleteFile(swcname);
+
+        reh = new RuntimeExecHelper(execArgs, dir);
+        reh.setPrintOutput(printOut);
+        reh.setTimeout(timeout);
+        long startTime = System.currentTimeMillis();
+        reh.run();
+        lastRunTime = System.currentTimeMillis() - startTime;
+
+    }
+
+    private String getSwc(String[] execArgs) {
+        // add swc that results from compile to private array of swcs
+        //parse execArgs to find -output value
+        //todo:this will need to be refactored when compc really works
+        String swc = "";
+        if (!bConfigFileArgs) {
+            for (int i = 0; i < execArgs.length; i++) {
+                if (execArgs[i].equals("--o") || execArgs[i].equals("-o") || execArgs[i].equals("--output") || execArgs[i].equals("-output")) {
+                    swc = execArgs[i + 1];
+                    swcs.add(swc);
+                    break;
+                }
+            }
+        } else {
+            String configFile = "";
+            for (int i = 0; i < execArgs.length; i++) {
+                if (execArgs[i].equals("--load-config") || execArgs[i].equals("-load-config")) {
+                    configFile = execArgs[i + 1];
+                    break;
+                }
+            }
+
+            try {
+                debug("configFile=" + configFile);
+                Document doc = DocumentUtils.parseDocument(configFile);
+                doc.getDocumentElement().normalize();
+                NodeList nd = doc.getElementsByTagName("output");
+                swc = nd.item(0).getFirstChild().getNodeValue();
+                debug(">>>>>>>>>>>swc=" + swc);
+                swcs.add(swc);
+            } catch (SAXException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+        }
+        return swc;
+    }
+
+    public List getSwcs() {
+        return swcs;
+    }
+
+    public long getLastRunTime() {
+        return lastRunTime;
+    }
+
+    public RuntimeExecHelper getRuntimeExecHelper() {
+        return reh;
+    }
+
+    public String[] getExecArgs() {
+        return execArgs;
+    }
+
+    public String getDir() {
+        return dir;
+    }
+    
+    public void setDir(String newDir) {
+        dir = newDir;
+    }
+
+    public void setPrintOut(boolean b) {
+        printOut = b;
+    }
+
+    //use the internal swc returned via compc and validate it
+    public void validateSwcs() {
+        validateSwcs(getSwcs());
+
+    }
+
+    private boolean validateSwc(String swc) {
+        //todo: this will need to be refactored to improve validation criteria
+        if (new File(swc).exists() && new File(swc).length() > 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private void validateSwcs(List swcs) {
+        Iterator it = swcs.iterator();
+        while (it.hasNext()) {
+            String swc = (String) it.next();
+            if (validateSwc(swc)) {
+                junit.framework.Assert.fail("compc failed to compile swc using these args: \n" + swc);
+            }
+        }
+    }
+
+
+//    todo: I think this is the correct thing do to when compc will really be working?? - kq
+    public String[] addSwcToClassPath(String[] mxmlArgs) {
+        //tack the swc onto the end of the --library-path
+
+        debug(">>>>>> original mxmlArgs >>> " + StringUtils.arrayToString(mxmlArgs));
+
+        validateSwcs();
+
+        boolean bFound = false;
+        String sep = " ";
+        int insertPos = 0;
+        List l = new Vector();
+        for (int i = 0; i < mxmlArgs.length; i++) {
+            if (mxmlArgs[i].trim().toLowerCase().indexOf("--library-path") > 0 || mxmlArgs[i].trim().toLowerCase().indexOf("-library-path") > 0) {
+                bFound = true;
+                insertPos = i;
+                debug("found library-path");
+            }
+            if (bFound) {
+                if ((mxmlArgs[i].startsWith("-") || mxmlArgs[i].startsWith("+")) && insertPos != i) {
+                    insertPos = i;
+                    bFound = false;
+                }
+                if (mxmlArgs[i].indexOf("=") > 0) {
+                    sep = ",";
+                    debug(">>> sepaprator is ',' ");
+                }
+            }
+            l.add(mxmlArgs[i]);
+
+        }
+        if (insertPos != 0) {
+            debug("found library-path at pos = " + insertPos);
+            Iterator it = getSwcs().iterator();
+            if (sep.equals(",")) {
+                String ins = (String) l.get(insertPos - 1);
+                while (it.hasNext()) {
+                    ins += sep + it.next();
+                }
+                l.set(insertPos - 1, ins);
+            } else {
+                while (it.hasNext()) {
+                    l.add(insertPos, (String) it.next());
+                    insertPos++;
+                }
+
+                //l.add(insertPos, "--");
+            }
+        } else {
+            //hack to make skinning.as last
+            boolean skinning = false;
+            if (((String) l.get(l.size() - 1)).trim().equalsIgnoreCase("skinning.as")) {
+                skinning = true;
+                l.remove(l.size() - 1);
+            }
+
+            //l.add("--library-path=");
+            String swcNames = "";
+            Iterator it = getSwcs().iterator();
+            while (it.hasNext()) {
+                //l.add((String) it.next());
+                swcNames += (String) it.next();
+            }
+			l.add("--library-path+=" + swcNames);
+			
+            if (skinning) {
+                if (!((String) l.get(l.size())).startsWith("-")) {
+                    l.add("--");
+                }
+                l.add("skinning.as");
+            }
+        }
+
+        mxmlArgs = (String[]) l.toArray(new String[]{});
+        debug(">>>>>> new mxmlArgs >>> " + StringUtils.arrayToString(mxmlArgs));
+        return mxmlArgs;
+
+    }
+
+
+}

Propchange: incubator/flex/trunk/mustella/java/src/utils/CompcUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/java/src/utils/CompileMxmlUtils.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/java/src/utils/CompileMxmlUtils.java?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/java/src/utils/CompileMxmlUtils.java (added)
+++ incubator/flex/trunk/mustella/java/src/utils/CompileMxmlUtils.java Wed May  2 22:44:38 2012
@@ -0,0 +1,187 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package utils;
+
+import java.io.File;
+import java.util.Vector;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * User: dschaffer
+ * Date: Mar 22, 2005
+ * Time: 3:28:38 PM
+ */
+public class CompileMxmlUtils {
+    private String swf;
+    private String fileBasedArgs;
+    private String mxmlc;
+    private String dir;
+    private long lastRunTime;
+    private RuntimeExecHelper reh;
+    private String execArgs[];
+    boolean printOut=false;
+    public void compile(String mxml) throws Exception {
+        compile(mxml,new String[]{});
+    }
+    public void compile(String mxml,String[] optionalArgs) throws Exception {
+        boolean debug=false;
+        debug=System.getProperty("debug")!=null && System.getProperty("debug").equals("true");
+        String mxmlcdir=System.getProperty("mxmlcdir");
+        String mxmlcexe=System.getProperty("mxmlcexe");
+        mxmlc=FileUtils.normalizeDirOS(mxmlcdir+"/"+mxmlcexe);
+        if (debug) {
+            System.out.println("mxmlcdir="+mxmlcdir);
+            System.out.println("mxmlcexe="+mxmlcexe);
+            System.out.println("mxmlc="+mxmlc);                                                                       
+        }
+        if (mxmlc==null || new File(mxmlc).isFile()==false) {
+            throw new Exception("mxml compiler not set correctly, mxmlc="+mxmlc);
+        }
+        String frameworks=System.getProperty("frameworks");
+        if (frameworks==null || new File(frameworks).isDirectory()==false) {
+            throw new Exception("frameworks not set correctly, frameworks="+frameworks);
+        }
+        if (debug) {
+            System.out.println("frameworks="+frameworks);
+        }
+        if (dir==null || new File(dir).isDirectory()==false) {
+            throw new Exception("working dir not set correctly, dir="+dir);
+        }
+
+        swf=mxml.substring(0,mxml.length()-4)+"swf";
+
+        String newArgs=null;
+
+        //if cmdLineArgs property exists used it for mxmlc args
+        String sysPropArgs=System.getProperty("cmdLineArgs");
+        if (sysPropArgs!=null && !sysPropArgs.equals("") ){
+            newArgs=sysPropArgs;
+            if (debug) {
+                System.out.println("sysPropArgs="+newArgs + " exists.  Reading args.");
+                System.out.println("sysPropArgs="+newArgs);
+            }
+        }
+
+        //see if there is a .args file in the folder with the same name as the folder
+        String folderpath= new File(mxml).getParent();
+        String foldername=new File(folderpath).getName();
+        String folderBasedArgs=folderpath + File.separator + foldername + ".args";
+        //if file with same name as mxml, but extension=args exists used it for mxmlc args
+        fileBasedArgs=mxml.substring(0,mxml.length()-4)+"args";
+
+        if (new File(fileBasedArgs).exists()==true) {
+            if (debug) {
+                System.out.println("fileBasedArgs="+fileBasedArgs + " exists.  Reading args.");
+            }
+            //read file and create string[] of args
+            String tmp=FileUtils.readFile(fileBasedArgs);
+
+            if (tmp !=null && !tmp.equals("") ){
+                newArgs=tmp;
+            }
+            if (debug) {
+                System.out.println("fileBasedArgs="+newArgs);
+            }
+
+        } else if (new File(folderBasedArgs).exists()==true)   {
+             if (debug) {
+                System.out.println("folderBasedArgs="+folderBasedArgs + " exists.  Reading args.");
+            }
+            //read file and create string[] of args
+            String tmp=FileUtils.readFile(folderBasedArgs);
+
+            if (tmp !=null && !tmp.equals("") ){
+                newArgs=tmp;
+            }
+            if (debug) {
+                System.out.println("folderBasedArgs="+newArgs);
+            }
+        }
+
+
+        if (newArgs != null){
+            StringTokenizer stok = new StringTokenizer(newArgs, " ");
+            stok.countTokens();
+            String[] tmp = new String[stok.countTokens()];
+            int count=0;
+            while (stok.hasMoreTokens()) {
+                tmp[count]=stok.nextToken();
+                count++;
+            }
+            optionalArgs=tmp;
+        }
+
+        //String mxmldir=FileUtils.getDirectory(mxml);
+        // mxunit setup?
+        String mxunit=System.getProperty("mxunit");
+        if (mxunit!=null) {
+            if (new File(mxunit).isDirectory()==false) {
+                throw new Exception("mxunit directory not set correctly, mxunit="+mxunit);
+            }
+            if (debug) {
+                System.out.println("mxunit="+mxunit);
+            }
+            mxunit=FileUtils.normalizeDir(mxunit);
+        }
+
+        String basedir=System.getProperty("basedir");
+        if (basedir!=null) {
+            if (new File(basedir).isDirectory()==false) {
+                throw new Exception("basedir directory not set correctly, basedir="+basedir);
+            }
+            if (debug) {
+                System.out.println("basedir="+basedir);
+            }
+            basedir=FileUtils.normalizeDir(basedir);
+        }
+
+        List execArgsList=new Vector();
+        execArgsList.add(mxmlc);
+        for (int i=0;i<optionalArgs.length;i++) {
+            execArgsList.add(optionalArgs[i]);
+        }
+        execArgsList.add(mxml);
+        execArgs=(String[])execArgsList.toArray(new String[]{});
+
+        if (debug) {
+        	System.out.println("cd "+dir);
+        	System.out.println(StringUtils.arrayToString(execArgs));
+        }
+
+        int timeout=300;
+        try { timeout=Integer.parseInt(System.getProperty("mxunit.compiler.timeout")); } catch (Exception e) {}
+		
+		//String java_home = System.getProperty("JAVA_HOME");
+		//String [] env = new String[]{"JAVA_HOME=" + java_home};
+        reh=new RuntimeExecHelper(execArgs,dir);
+        reh.setPrintOutput(printOut);
+        reh.setTimeout(timeout);
+        long startTime=System.currentTimeMillis();
+        reh.run();
+        lastRunTime=System.currentTimeMillis()-startTime;
+    }
+    public String getSwf() { return swf; }
+    public long getLastRunTime() { return lastRunTime; }
+    public RuntimeExecHelper getRuntimeExecHelper() { return reh; }
+    public String[] getExecArgs() { return execArgs; }
+    public void setDir(String dir) { this.dir=dir; }
+    public String getDir() { return dir; }
+    public void setPrintOut(boolean b)  { printOut=b; }
+}

Propchange: incubator/flex/trunk/mustella/java/src/utils/CompileMxmlUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/java/src/utils/DocumentUtils.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/java/src/utils/DocumentUtils.java?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/java/src/utils/DocumentUtils.java (added)
+++ incubator/flex/trunk/mustella/java/src/utils/DocumentUtils.java Wed May  2 22:44:38 2012
@@ -0,0 +1,148 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package utils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+import org.apache.xml.serialize.TextSerializer;
+import org.apache.xml.serialize.XMLSerializer;
+import org.apache.xml.serialize.OutputFormat;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import java.io.Writer;
+import java.io.IOException;
+import java.io.File;
+
+/**
+ * @author Peter Farland
+ */
+public class DocumentUtils
+{
+	private DocumentUtils()
+	{
+	}
+
+	public static DocumentBuilder getBuilder(boolean ignoreComments, boolean validating, boolean ignoreContentWhitespace, boolean isNamespaceAware)
+	{
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		factory.setIgnoringComments(ignoreComments);
+		factory.setValidating(validating);
+		factory.setIgnoringElementContentWhitespace(ignoreContentWhitespace);
+		factory.setNamespaceAware(isNamespaceAware);
+
+		DocumentBuilder builder = null;
+
+		try
+		{
+			builder = factory.newDocumentBuilder();
+		}
+		catch (Exception ex)
+		{
+			ex.printStackTrace();
+		}
+
+		return builder;
+	}
+
+	public static Document newDocument()
+	{
+		DocumentBuilder builder = getBuilder(false, false, false, true);
+		return builder.newDocument();
+	}
+
+	public static Document parseDocument(String path) throws SAXException, IOException
+	{
+		return parseDocument(path, getBuilder(false, false, false, true));
+	}
+
+	public static Document parseDocument(String path, DocumentBuilder builder) throws SAXException, IOException
+	{
+		Document doc = builder.parse(path);
+		return doc;
+	}
+
+	public static Document parseDocument(File file) throws SAXException, IOException
+	{
+		return parseDocument(file, getBuilder(false, false, false, true));
+	}
+
+	public static Document parseDocument(File file, DocumentBuilder builder) throws SAXException, IOException
+	{
+		Document doc = builder.parse(file);
+		return doc;
+	}
+
+	public static void writeDocument(Document doc, Writer writer) throws IOException
+	{
+		writeDocument(doc, writer, null);
+	}
+
+	public static void writeDocument(Document doc, Writer writer, OutputFormat outputFormat) throws IOException
+	{
+		XMLSerializer serializer;
+
+		if (outputFormat != null)
+			serializer = new XMLSerializer(outputFormat);
+		else
+			serializer = new XMLSerializer();
+
+		serializer.setOutputCharStream(writer);
+		serializer.serialize(doc);
+	}
+
+	public static Element getFirstChild(Element element, String childName)
+	{
+		Element e = null;
+
+		NodeList nl = element.getElementsByTagName(childName);
+		if (nl != null)
+		{
+			e = (Element)nl.item(0);
+		}
+
+		return e;
+	}
+
+	public static Element getFirstChildByNS(Element node, String ns, String localName)
+	{
+		Element e = null;
+
+		NodeList nl = node.getElementsByTagNameNS(ns, localName);
+		if (nl != null)
+		{
+			e = (Element)nl.item(0);
+		}
+
+		return e;
+	}
+
+	public static void removeChildren(Node parent, NodeList nodelist)
+	{
+		for (int i = 0; i < nodelist.getLength(); i++)
+		{
+			parent.removeChild(nodelist.item(i));
+		}
+	}
+
+
+}

Propchange: incubator/flex/trunk/mustella/java/src/utils/DocumentUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/java/src/utils/FileUtils.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/java/src/utils/FileUtils.java?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/java/src/utils/FileUtils.java (added)
+++ incubator/flex/trunk/mustella/java/src/utils/FileUtils.java Wed May  2 22:44:38 2012
@@ -0,0 +1,353 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package utils;
+
+import java.io.*;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * User: dschaffer
+ * Date: Mar 8, 2005
+ * Time: 11:21:03 AM
+ */
+public class FileUtils {
+    public static String normalizeDir(String dir) {
+        if (dir==null) dir=".";
+        try {
+            dir=new File(dir).getCanonicalPath();
+        } catch (IOException e) {
+        }
+        dir=dir.replace('\\','/');
+        if (dir.endsWith("/" ) || dir.endsWith("\\")) {
+            dir=dir.substring(0,dir.length()-1);
+        }
+        return dir;
+    }
+
+    public static String normalizeDirOS(String dir) {
+        if (dir==null) dir=".";
+        try {
+            dir=new File(dir).getCanonicalPath();
+        } catch (IOException e) {
+        }
+        dir=dir.replace('\\',File.separatorChar);
+        dir=dir.replace('/',File.separatorChar);
+        if (dir.endsWith("/" ) || dir.endsWith("\\")) {
+            dir=dir.substring(0,dir.length()-1);
+        }
+        return dir;
+    }
+
+    public static String get8Dot3Path(String path) {
+
+        path = normalizeDir(path);
+        StringTokenizer tokenizer = new StringTokenizer(path, "/");
+
+        String newPath = "";
+        while (tokenizer.hasMoreElements()) {
+            String currentToken = (String)tokenizer.nextElement();
+
+            int indexOfDot = currentToken.indexOf(".");
+            String beforeDot = indexOfDot > 0? currentToken.substring(0, indexOfDot ) : currentToken;
+            String afterDot = indexOfDot > 0? currentToken.substring(indexOfDot) : "/";
+
+            if (beforeDot.length() <= 8) {
+                newPath += beforeDot + afterDot;
+            } else {
+                newPath += beforeDot.substring(0, 6) + "~1" + afterDot;
+            }
+        }
+
+        if (newPath.substring(newPath.length()).equals("/"))
+            newPath = newPath.substring(0, newPath.length() - 1);
+
+        return newPath;
+    }
+
+    public static String getDirectory(String file) {
+        file=file.replace('\\',File.separatorChar);
+        file=file.replace('/',File.separatorChar);
+        String dir=file.substring(0,file.lastIndexOf(File.separatorChar));
+        return dir;
+    }
+    public static String getFile(String file) {
+        file=file.replace('\\',File.separatorChar);
+        file=file.replace('/',File.separatorChar);
+        String dir=file.substring(file.lastIndexOf(File.separatorChar)+1);
+        return dir;
+    }
+    public static void writeFile(String name,String contents) throws Exception {
+        BufferedWriter bw=new BufferedWriter(new FileWriter(name));
+        bw.write(contents);
+        bw.flush();
+        bw.close();
+    }
+
+    public static void writeFileUTF(String name,String contents) throws Exception {
+        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(name), "UTF-8"));
+        bw.write(contents);
+        bw.flush();
+        bw.close();
+    }
+
+    public static void writeBinaryFile(String name,String fromName) throws Exception {
+
+        byte byteArr[]=new byte[8192];
+        String contents="";
+        FileInputStream fin=new FileInputStream(fromName);
+        FileOutputStream fos=new FileOutputStream(name);
+        int len;
+        while ((len=fin.read(byteArr, 0, 8192))!=-1) {
+            fos.write(byteArr);
+        }
+        fin.close();
+        fos.close();
+    }
+    public static String readFile(String name) throws Exception {
+        char ch[]=new char[8192];
+        String contents="";
+        BufferedReader br=new BufferedReader(new FileReader(name));
+        int len;
+        while ((len=br.read(ch,0,8192))!=-1) {
+            contents+=new String(ch,0,len);
+        }
+        br.close();
+        return contents;
+    }
+
+    public static String readFileUTF(String name) throws Exception {
+        char ch[]=new char[8192];
+        String contents="";
+        BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(name), "UTF-8"));
+        int len;
+        while ((len=br.read(ch,0,8192))!=-1) {
+            contents+=new String(ch,0,len);
+        }
+        br.close();
+        return contents;
+    }
+
+    public static List readLines(String name) throws Exception {
+        String contents=readFile(name);
+        List lines=new Vector();
+        while (contents.indexOf("\n")>-1) {
+            String line=contents.substring(0,contents.indexOf("\n"));
+            contents=contents.substring(contents.indexOf("\n")+1);
+            line=line.trim();
+            lines.add(line);
+        }
+        if (contents.length()>0) {
+            lines.add(contents);
+        }
+        return lines;
+    }
+    public static void copyFile(String fromFile,String toFile) throws Exception {
+        if (new File(toFile).exists()==true) {
+            new File(toFile).delete();
+        }
+        writeFile(toFile,readFile(fromFile));
+    }
+    public static void copyBinaryFile(String fromFile,String toFile) throws Exception {
+	        if (new File(toFile).exists()==true) {
+	            new File(toFile).delete();
+	        }
+	        writeBinaryFile(toFile, fromFile);
+    }
+    public static void copyDir(String dir,String todir) throws Exception {
+        if (new File(todir).exists()==false) {
+            new File(todir).mkdirs();
+        }
+        File d = new File(dir);
+        if (!d.isDirectory())
+        {
+            System.err.println("warning: " + dir + " is not a directory");
+            return;
+        }
+        File files[]=d.listFiles();
+        if (files != null)
+        {
+            for (int i=0;i<files.length;i++) {
+                if (files[i].isDirectory()) {
+                    copyDir(files[i].toString(),todir+"/"+getFile(files[i].toString()));
+                } else {
+                    copyFile(files[i].toString(),todir+"/"+getFile(files[i].toString()));
+                }
+            }
+        }
+
+    }
+
+    public static void copyBinaryDir(String dir,String todir) throws Exception {
+        if (new File(todir).exists()==false) {
+            new File(todir).mkdirs();
+        }
+        File d = new File(dir);
+        if (!d.isDirectory())
+        {
+            System.err.println("warning: " + dir + " is not a directory");
+            return;
+        }
+        File files[]=d.listFiles();
+        if (files != null)
+        {
+            for (int i=0;i<files.length;i++) {
+                if (files[i].isDirectory()) {
+                    copyBinaryDir(files[i].toString(),todir+"/"+getFile(files[i].toString()));
+                } else {
+                    copyBinaryFile(files[i].toString(),todir+"/"+getFile(files[i].toString()));
+                }
+            }
+        }
+
+    }
+
+    public static void deleteFile(String name){
+        if (new File(name).exists())
+            new File(name).delete();
+    }
+
+	/**
+	* Deletes a file or directory and all of its contents.
+	**/
+    public static void recursivelyDelete(String name){
+        File curFile = new File(name);
+		File subFile = null;
+		int i = 0;
+
+		try{
+			if (curFile.exists()){
+				if(curFile.isDirectory()){
+					String[] arrFiles = curFile.list();
+
+					for(i = 0; i < Array.getLength(arrFiles); ++i){
+						subFile = new File(curFile + File.separator + arrFiles[i]);
+						recursivelyDelete(subFile.getCanonicalPath());
+					}
+				}
+
+				// Now we have a file or an empty dir we can delete.
+				if( !curFile.delete() ){
+					//System.out.println("Could not delete " + curFile.getCanonicalPath() + ".");
+				}
+			}
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+    }
+
+    public static String convertCygwinPath(String file) {
+        if (file.startsWith("\"")) file=file.substring(1);
+        if (file.endsWith("\"")) file=file.substring(0,file.length()-1);
+        if (new File(file).exists())
+            return file;
+        if (file.startsWith("/cygdrive"))
+            file=file.substring(9);
+        if (file.startsWith("/") && file.substring(2,3).equals("/")) {
+            file=file.substring(1,2)+":"+file.substring(2);
+        }
+        return file;
+    }
+    public static boolean getResult(String file) {
+        boolean result=true;
+        try {
+            String s=readFile(file);
+            if (s.indexOf("false")>-1) {
+                result=false;
+            }
+        } catch (Exception e) {
+        }
+        return result;
+    }
+    public static boolean getResult() {
+        return getResult(System.getProperty("basedir","."));
+    }
+    public static void updateResult(boolean bool) {
+        updateResult(System.getProperty("basedir",".")+"/testresults.properties",bool);
+    }
+    public static void updateResult(String file,boolean bool) {
+        System.out.println("testresults "+(bool? "PASSED":"FAILED")+" writing to "+file);
+        boolean result=getResult(file);
+        try {
+            writeFile(file,"result="+(result&bool));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static String removeCommentsFromFile(String content) {
+        content = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL).matcher(content).replaceAll("");
+        content = content.replaceAll("//.*", "");
+        return content;
+    }
+
+
+    public static void main(String[] args) {
+        get8Dot3Path("c:\\program files\\internet explorer\\iexplore.exe");
+    }
+
+	/**
+	 * Returns all files (no directories) found in and below rootDir, with the given
+	 * filter.
+	 **/
+	public static ArrayList listFilesRecursively( File rootDir, FilenameFilter filter ){
+		ArrayList list = new ArrayList();
+		File[] files = rootDir.listFiles( filter );
+
+		for( int i = 0; i < Array.getLength( files ); ++i ){
+			if( files[i].isFile() ){
+				list.add( files[i] );
+			}else if( files[i].isDirectory() ){
+				list.addAll( listFilesRecursively( files[i], filter ) );
+			}
+		}
+
+		return list;
+	}
+	
+	/**
+	 * Returns all top level directories and files (no sub directories) found in and below rootDir and 
+	 * swfdir, with the given filter. Note that filter does not work in sub directories.
+	 **/
+	public static ArrayList listTopLevelDirectoriesAndFiles( File rootDir, FilenameFilter filter ){
+		ArrayList list = new ArrayList();
+		File[] files = rootDir.listFiles( filter );
+
+		for( int i = 0; i < Array.getLength( files ); ++i ){
+			try {
+				String filePath = files[i].getCanonicalPath().toLowerCase();
+				if (filePath.endsWith(File.separator + "swfs") == false) {
+					list.add( files[i] );
+				}
+				else 
+				{
+					list.addAll(listTopLevelDirectoriesAndFiles(files[i], filter));
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+
+		return list;
+	}
+}

Propchange: incubator/flex/trunk/mustella/java/src/utils/FileUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/java/src/utils/MobileUtil.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/java/src/utils/MobileUtil.java?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/java/src/utils/MobileUtil.java (added)
+++ incubator/flex/trunk/mustella/java/src/utils/MobileUtil.java Wed May  2 22:44:38 2012
@@ -0,0 +1,1168 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package utils;
+
+import java.io.*;
+import java.lang.reflect.Array;
+import java.net.*;
+import java.util.*;
+import javax.imageio.*;
+//import javax.mail.*;
+//import javax.mail.internet.*;
+//import utils.HtmlNotify;
+
+public class MobileUtil {
+
+	// OSs
+	public static final String ANDROID_OS = "android";
+	public static final String IOS = "iphone";	// "iPhone OS" is what the iPod Touch 4G returns, anyway.
+	public static final String QNX = "qnx";
+	public static final String MAC = "mac";
+	public static final String WIN = "windows";
+	public static final String WIN2 = "win";
+
+	// devices
+	// Get rid of these two when we do device types (soon).
+	public static final String ANDROID = "android";
+	public static final String ANDROID2 = "Android";
+	public static final String PLAYBOOK = "playbook";
+	public static final String DESIRE = "desire";
+	public static final String DROID = "droid";
+	public static final String DROID_2 = "droid2";
+	public static final String DROID_X = "droidX";
+    public static final String DROID_PRO = "droidPro";
+	public static final String NEXUS_ONE = "nexusOne";
+	public static final String EVO = "evo";
+	public static final String INCREDIBLE = "incredible";
+	public static final String XOOM = "xoom";
+	public static final String SDCARD_DIR = "/sdcard/mustella";
+	public static final String IPAD = "iPad";
+	public static final String IPAD2 = "iPad2";
+	public static final String IPOD_TOUCH_3GS = "iPodTouch3GS";
+	public static final String IPOD_TOUCH_4G = "iPodTouch4G";
+	public static final String ANDROID_TABLET = "androidTablet"; // not used anywhere yet, not sure if this is a good name.
+
+
+	// Useful collections
+    public static final String[] DEVICES_USING_ANDROID = {ANDROID, ANDROID2, DESIRE, DROID, DROID_2, DROID_X, DROID_PRO, NEXUS_ONE, EVO, INCREDIBLE, ANDROID_TABLET, XOOM};
+	public static final String[] DEVICES_USING_IOS = {IPAD, IPAD2, IPOD_TOUCH_3GS, IPOD_TOUCH_4G};
+	public static final String[] DEVICES_USING_QNX = {PLAYBOOK};
+    public static final String[] DEVICES_USING_SDCARD = {ANDROID, ANDROID2, DESIRE, DROID, DROID_2, DROID_X, DROID_PRO, NEXUS_ONE, EVO, INCREDIBLE, ANDROID_TABLET, XOOM};
+    public static final String[] DEVICES_AROUND_160PPI = {DROID_PRO, ANDROID_TABLET, XOOM, IPOD_TOUCH_3GS, IPAD, IPAD2, PLAYBOOK};
+	public static final String[] DEVICES_AROUND_240PPI = {ANDROID, ANDROID2, DESIRE, DROID, DROID_2, DROID_X, NEXUS_ONE, EVO, INCREDIBLE};
+	public static final String[] DEVICES_AROUND_320PPI = {IPOD_TOUCH_4G};
+
+	// Other
+	public static final String MOBILE_FRAMEWORK_DIR = "MobileConfig";
+	public static final String IOS_PRODUCTNAME = "ProductName:";
+	public static final String IOS_PRODUCTVERSION = "ProductVersion:";
+	public static final String IOS_PROCESSOR = "Processor type:";
+	public static final String IOS_MEMORYAVAILABLE = "Primary memory available:";
+
+	/**
+	 * getOSForDevice
+	 * Given a device type, return the OS.  e.g. Input "nexus_one", get back "android".
+	 **/
+	public static String getOSForDevice(String device_name){
+		int i = 0;
+		String ret = null;
+
+		for( i = 0; i < Array.getLength( DEVICES_USING_ANDROID ); ++i){
+			if( device_name.compareToIgnoreCase( DEVICES_USING_ANDROID[ i ] ) == 0 ){
+				ret = ANDROID_OS;
+			}
+		}
+
+		if( ret == null ){
+			for( i = 0; i < Array.getLength( DEVICES_USING_IOS ); ++i){
+				if( device_name.compareToIgnoreCase( DEVICES_USING_IOS[ i ] ) == 0 ){
+					ret = IOS;
+				}
+			}
+		}
+
+		if( ret == null ){
+			for( i = 0; i < Array.getLength( DEVICES_USING_QNX ); ++i){
+				if( device_name.compareToIgnoreCase( DEVICES_USING_QNX[ i ] ) == 0 ){
+					ret = QNX;
+				}
+			}
+		}
+
+		// When we run mobile tests on the desktop...
+		if( ret == null ){
+			if( device_name.compareToIgnoreCase( MobileUtil.MAC ) == 0 )
+				return MobileUtil.MAC;
+			else if( device_name.compareToIgnoreCase( MobileUtil.WIN ) == 0 )
+				return MobileUtil.WIN;
+			else if( device_name.compareToIgnoreCase( MobileUtil.WIN2 ) == 0 )
+				return MobileUtil.WIN;
+		}
+
+		return ret;
+	}
+
+	/**
+	 * getDeviceIds
+	 * Fetches the serial numbers of all devices available if they are in allowedIds.
+	 */
+	public static ArrayList getAndroidDeviceIds(String adb, int run_id, String[] allowedIds){
+		String line = null;
+		String body = null;
+		Process p = null;
+		ArrayList ret = new ArrayList();
+		int numOfflineDevices = 0;
+		int numReadyDevices = 0;
+		int i = 0;
+		InetAddress ia = null;
+
+		/**
+		if(allowedIds != null){
+			System.out.println("allowedIds=" + allowedIds);
+			for(i = 0; i < allowedIds.length; ++i){
+				System.out.println("\t" + allowedIds[i]);
+			}
+		}
+		**/
+
+		try{
+			if( new File(adb).exists() ){
+				String[] listDevices = { adb, "devices" };
+				p = Runtime.getRuntime().exec( listDevices );
+
+				BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+
+				// Collect all of the device serial numbers.  Note that these serial numbers aren't the
+				// same as the serial numbers found on the back of a device.
+				while ( true ){
+					line = br.readLine();
+
+					if( (line == null) || (line.trim().compareToIgnoreCase("") == 0) ){
+						break;
+					}
+
+					if( line.indexOf( "List of devices" ) == -1 ){
+						if( line.indexOf( "device" ) > -1  ){
+							++numReadyDevices;
+							line = line.substring( 0, line.indexOf( "device" ) );
+							line = line.trim();
+
+							//System.out.println("getAndroidDeviceIds: line=" + line);
+
+							// Make sure we're allowed to use this device.
+							if( allowedIds != null ){
+								for( i = 0; i < allowedIds.length; ++i ){
+									if( line.compareToIgnoreCase( allowedIds[i].trim() ) == 0 ){
+										System.out.println("Adding device: '" + line + "'");
+										ret.add( line );
+									}else{
+										//System.out.println("Found device '" + line + "', but that does not match " + allowedIds[i].trim());
+									}
+								}
+							}else{
+								// If no restricted list of IDs was given, return all of them.
+								ret.add( line );
+							}
+
+						} else if( line.indexOf( "offline" ) > -1  ) {
+							++numOfflineDevices;
+							line = line.substring( 0, line.indexOf( "offline" ) );
+							line = line.trim();
+							System.out.println("Found offline device: '" + line + "'");
+						}
+					}
+				}
+
+				if( ( numReadyDevices == 0 || numOfflineDevices > 0 ) && run_id > -1 ){
+					try {
+						System.out.println("There are no devices reporting at all.");
+
+						/*
+						ia = InetAddress.getLocalHost();
+						String hostname = ia.getHostName();
+
+						body = "(The following message is automatically generated by the Mustella framework.)  Device trouble is ocurring on " + hostname + ".  ";
+
+						if( numOfflineDevices > 0 ){
+							body = body + "We have " + Integer.toString(numOfflineDevices) + " offline device(s).  ";
+						}
+
+						if( numReadyDevices + numOfflineDevices == 0 ){
+							body = body + "There are no devices reporting at all.  ";
+						}
+
+						if( numReadyDevices > 0 ){
+							body = body + "On the bright side, at least we have " + Integer.toString(numReadyDevices) + " device(s) still able to respond, so all is not lost.  ";
+						}
+
+						body = body + "Can you please help?  Thanks!  ";
+
+						InternetAddress[] to = new InternetAddress[1];
+						to[0] = new InternetAddress("MustellaMobileResults@adobe.com");
+						HtmlNotify hn = new HtmlNotify();
+						hn.sendMessage("inner-relay-1.corp.adobe.com",
+									   "rvollmar@adobe.com",
+									   to,
+									   hostname + " mustella device offline",
+									   body);
+						*/
+
+					}
+					catch(Exception e){
+						e.printStackTrace();
+					}
+				}
+			}
+		}catch( IOException e ){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+	/**
+	 * getAndroidOsVersion
+	 * Asks a device for its OS version.
+	 **/
+	public static String getAndroidOsVersion( String adb, String deviceId ){
+		String line = null;
+		String ret = null;
+		Process p = null;
+
+		try{
+			String[] getstats = { adb, "-s", deviceId, "shell", "getprop", "ro.build.version.release" };
+			p = Runtime.getRuntime().exec( getstats );
+
+			BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+
+			while ( true ){
+				line = br.readLine();
+
+				if( line == null ){
+					break;
+				} else {
+					ret = line;
+				}
+			}
+		}catch( IOException e ){
+			e.printStackTrace();
+		}
+
+		// Remove the period (replace() works OK if there isn't one).
+		ret = ret.replace(".", "");
+
+		return MobileUtil.ANDROID_OS + ret;
+	}
+
+	/**
+	 * getDeviceDensity
+	 * Returns a number to use for the PPI.
+	 * system.Capabilities gives an exact number, like 254.  We don't want that.
+	 * The device itself returns a general number, like "240", today, but who knows about later.
+	 * So we're just going to hard code the sorting of devices into groups to reduce uncertainty.
+	 **/
+	//public static int getDeviceDensity( String adb, String deviceId ){
+	public static int getDeviceDensity( String deviceId ){
+
+		int i = 0;
+		int ret = 0;
+
+		for( i = 0; i < Array.getLength( DEVICES_AROUND_160PPI ); ++i ){
+			if( deviceId.compareToIgnoreCase( DEVICES_AROUND_160PPI[ i ] ) == 0 )
+				ret = 160;
+		}
+
+		for( i = 0; i < Array.getLength( DEVICES_AROUND_240PPI ); ++i ){
+			if( deviceId.compareToIgnoreCase( DEVICES_AROUND_240PPI[ i ] ) == 0 )
+				ret = 240;
+		}
+
+		for( i = 0; i < Array.getLength( DEVICES_AROUND_320PPI ); ++i ){
+			if( deviceId.compareToIgnoreCase( DEVICES_AROUND_320PPI[ i ] ) == 0 )
+				ret = 320;
+		}
+
+		return ret;
+		/**
+		String line = null;
+		String ret = null;
+		Process p = null;
+
+		try{
+			String[] getstats = { adb, "-s", deviceId, "shell", "getprop", "ro.sf.lcd_density" };
+			p = Runtime.getRuntime().exec( getstats );
+
+			BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+
+			while ( true ){
+				line = br.readLine();
+
+				if( line == null ){
+					break;
+				} else {
+					ret = line;
+				}
+			}
+		}catch( IOException e ){
+			e.printStackTrace();
+		}
+
+		return ret;
+		**/
+	}
+
+	/**
+	 * getAndroidModel
+	 * Asks a device for its model.  It returns, for example, "Nexus One".
+	 * We don't use this yet, but it might be handy.
+	 **/
+	public static String getAndroidModel( String adb, String deviceId ){
+		String line = null;
+		String ret = null;
+		Process p = null;
+
+		try{
+			String[] getstats = { adb, "-s", deviceId, "shell", "getprop", "ro.product.model" };
+			p = Runtime.getRuntime().exec( getstats );
+
+			BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+
+			while ( true ){
+				line = br.readLine();
+
+				if( line == null ){
+					break;
+				} else {
+					ret = line;
+				}
+			}
+		}catch( IOException e ){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+	/**
+	 * pingIOSDevice
+	 * Checks to see if the device we're ssh'ing to is an "iPhone".
+	 * sw_vers returns:
+	 *   ProductName:    iPhone OS
+	 *   ProductVersion: 4.1
+	 *   BuildVersion:   8B118
+	 **/
+	public static boolean pingIOSDevice(){
+		String line = null;
+		boolean ret = false;
+		Process p = null;
+
+		try{
+			String[] sw_vers = { "ssh", "-p", "2222", "root@localhost", "sw_vers" };
+			p = Runtime.getRuntime().exec( sw_vers );
+
+			BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+
+			System.out.println("Gathering device details");
+
+			while ( true ){
+				line = br.readLine();
+
+				if( line == null )
+					break;
+
+				System.out.println("\t" + line);
+
+				if( line.indexOf( IOS_PRODUCTNAME ) > -1 ){
+					line = line.substring( IOS_PRODUCTNAME.length() ).trim();
+
+					if( line.toLowerCase().indexOf( IOS ) > -1 ){
+						ret = true;
+					}
+				}
+			}
+		}catch( IOException e ){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+	/**
+	 * getIOSVersion
+	 * Asks a device for its OS version.
+	 * sw_vers returns:
+	 *   ProductName:    iPhone OS
+	 *   ProductVersion: 4.1
+	 *   BuildVersion:   8B118
+	 **/
+	public static String getIOSVersion(){
+		String line = null;
+		String ret = null;
+		Process p = null;
+
+		try{
+			String[] sw_vers = { "ssh", "-p", "2222", "root@localhost", "sw_vers" };
+			p = Runtime.getRuntime().exec( sw_vers );
+
+			BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+
+			while ( true ){
+				line = br.readLine();
+
+				if( line == null )
+					break;
+
+				if( line.indexOf( IOS_PRODUCTVERSION ) > -1 ){
+					ret = line.substring( IOS_PRODUCTVERSION.length() ).trim();
+					System.out.println("getIOSVersion found "  + ret);
+				}
+			}
+		}catch( IOException e ){
+			e.printStackTrace();
+		}
+
+
+		return ret;
+	}
+
+	/**
+	 * getIOSProcessor
+	 * Asks a device for its architecture
+	 * hostinfo returns:
+	 *   Mach kernel version:
+	 *   Darwin Kernel Version 10.3.1: Wed Aug  4 22:35:51 PDT 2010; root:xnu-1504.55.33~10/RELEASE_ARM_S5L8930X
+	 *   Kernel configured for a single processor only.
+	 *   1 processor is physically available.
+	 *   1 processor is logically available.
+	 *   Processor type: armv7 (arm v7)
+	 *   Processor active: 0
+	 *   Primary memory available: 247.00 megabytes
+	 *   Default processor set: 27 tasks, 195 threads, 1 processors
+	 *   Load average: 0.05, Mach factor: 0.94
+	 **/
+	public static String getIOSProcessor(){
+		String line = null;
+		String ret = null;
+		Process p = null;
+
+		try{
+			String[] hostinfo = { "ssh", "-p", "2222", "root@localhost", "hostinfo" };
+			p = Runtime.getRuntime().exec( hostinfo );
+
+			BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+
+			while ( true ){
+				line = br.readLine();
+
+				if( line == null )
+					break;
+
+				if( line.indexOf( IOS_PROCESSOR ) > -1 ){
+					ret = line.substring( IOS_PROCESSOR.length() ).trim(); // Now we have "armv7 (arm v7)"
+
+					if( ret.indexOf( " " ) > -1 ){
+						ret = ret.substring( 0, ret.indexOf( " " ) ).trim();
+					}
+
+					System.out.println("getIOSProcessor found "  + ret);
+				}
+			}
+		}catch( IOException e ){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+	/**
+	 * getIOSMemoryAvailable
+	 * Asks a device for its available memory
+	 * hostinfo returns:
+	 *   Mach kernel version:
+	 *   Darwin Kernel Version 10.3.1: Wed Aug  4 22:35:51 PDT 2010; root:xnu-1504.55.33~10/RELEASE_ARM_S5L8930X
+	 *   Kernel configured for a single processor only.
+	 *   1 processor is physically available.
+	 *   1 processor is logically available.
+	 *   Processor type: armv7 (arm v7)
+	 *   Processor active: 0
+	 *   Primary memory available: 247.00 megabytes
+	 *   Default processor set: 27 tasks, 195 threads, 1 processors
+	 *   Load average: 0.05, Mach factor: 0.94
+	 **/
+	public static String getIOSMemoryAvailable(){
+		String line = null;
+		String ret = null;
+		Process p = null;
+
+		try{
+			String[] hostinfo = { "ssh", "-p", "2222", "root@localhost", "hostinfo" };
+			p = Runtime.getRuntime().exec( hostinfo );
+
+			BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+
+			while ( true ){
+				line = br.readLine();
+
+				if( line == null )
+					break;
+
+				if( line.indexOf( IOS_MEMORYAVAILABLE ) > -1 ){
+					ret = line.substring( IOS_MEMORYAVAILABLE.length() ).trim();
+
+					System.out.println("getIOSMemoryAvailable found "  + ret);
+				}
+			}
+		}catch( IOException e ){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Restarts the springboard.  Hopefully someday we can bypass the swipe!
+	 **/
+	public static boolean restartSpringboard( String message ){
+		int inputData = -1;
+		BufferedReader keyboardInput = null;
+		Process p = null;
+		boolean ret = false;
+
+		try{
+			String[] cmd = { "ssh", "-p", "2222", "root@localhost", "launchctl", "stop", "com.apple.SpringBoard" };
+			p = Runtime.getRuntime().exec( cmd );
+			p.waitFor();
+
+			System.out.println(message);
+			keyboardInput = new BufferedReader( new InputStreamReader( System.in ) );
+			inputData = keyboardInput.read();
+			System.out.println("got it, thanks");
+
+			ret = true;
+		}catch(Exception e){
+			e.printStackTrace();
+			ret = false;
+		}
+
+		return ret;
+	}
+
+	/**
+	 * rebootIOSDevice
+	 * Reboots, then waits for the device to become responsive to ssh commands.
+	 **/
+	public static void rebootIOSDevice(){
+		boolean ready = false;
+		Process p = null;
+
+		try{
+			String[] reboot = { "ssh", "-p", "2222", "root@localhost", "reboot" };
+			p = Runtime.getRuntime().exec( reboot );
+
+			while( !ready ){
+				System.out.println("Waiting for device to reboot...");
+				Thread.sleep( 1000 );
+				ready = pingIOSDevice();
+			}
+
+		}catch( Exception e ){
+			e.printStackTrace();
+		}
+
+		return;
+	}
+
+	/**
+	 * Calls uicache on the device.  This refreshes the Springboard's list of apps
+	 * so we don't have to swipe.  There are reports that it can sometimes take  a
+	 * while to take effect, so we have some "wait" parameters, just in case.
+	 **/
+	public static void refreshIOSUICache(){
+		refreshIOSUICache( 0, 0 );
+	}
+
+	public static void refreshIOSUICache( int attempts, int waitMillis ){
+		Process p = null;
+		int ret = -1;
+		int i = 0;
+
+		try{
+			for( i = 0; i < attempts; ++i ){
+				System.out.println( "Calling uicache" );
+				String[] cmdRefresh = { "ssh", "-p", "2222", "root@localhost", "/usr/bin/uicache" };
+				p = Runtime.getRuntime().exec( cmdRefresh );
+				p.waitFor();
+				//System.out.println( "Giving iOS " + waitMillis + " ms to catch up" );
+				Thread.sleep( waitMillis );
+			}
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Copies a file or directory to the device.  Returns true if to is present afterward.
+	 **/
+	public static void copyToIOS( String from, String to ){
+		Process p = null;
+		File fromFile = new File( from );
+		String[] dirs = null;
+		String curDir = null;
+		String finalDir = null;
+
+		try{
+			if( !fromFile.exists() ){
+				System.out.println("source " + from + " not found.");
+			}
+
+			if( to.trim().compareTo("") == 0 ){
+				System.out.println("dest " + to + " is not valid.");
+			}
+
+			// ISSUE: sometimes we pass in a dir and want the dir, sometimes we want the CONTENTS of the dir.
+			// Need to call this consistently and handle consistently.
+			// Maybe if it ends in *, copy contents, otherwise copy the dir itself.
+			// This should be more elegant, but I'm checking it in as is b/c people are blocked.
+
+			// If it's a file, be sure the parent directory exists.
+			if( new File( from ).isFile() ){
+				curDir = to.substring( 0, to.lastIndexOf( "/" ) );
+				String[] cmdMkdir = { "ssh", "-p", "2222", "root@localhost", "mkdir", "-p", curDir };
+				p = Runtime.getRuntime().exec( cmdMkdir );
+				p.waitFor();
+			}
+
+			//System.out.println("copying to iOS: " + from);
+			String[] cmdCopy = { "scp", "-P", "2222", "-r", from, "root@localhost:" + to };
+			p = Runtime.getRuntime().exec( cmdCopy );
+			p.waitFor();
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Copies a file or directory from the device. Returns true if to is present afterward.
+	 * Note that true will be returned if the copy failed and the file existed already.
+	 * It's up to the caller to delete to first if desired.
+	 **/
+	public static boolean copyFromIOS( String from, String to ){
+		Process p = null;
+		boolean ret = false;
+
+		try{
+			if( findIOSFile( from ) == null ){
+				System.out.println("MobileUtil.copyFromIOS: Source file " + from + " not found.");
+				return ret;
+			}
+
+			if( to.trim().compareTo("") == 0 ){
+				System.out.println("MobileUtil.copyFromIOS: Dest " + to + " is not valid.");
+				return ret;
+			}
+
+			//System.out.println("Copying from " + from + " to " + to);
+			String[] cmdCopy = { "scp", "-P", "2222", "-r", "root@localhost:" + from, to };
+			p = Runtime.getRuntime().exec( cmdCopy );
+			p.waitFor();
+
+			if( new File( to ).exists() ){
+				ret = true;
+			}
+
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Launches the given app.  If wait is true, waits for it to start and returns the process ID.
+	 *
+	 **/
+	public static int launchIOSApp( String appName, boolean wait, long launchTimeout ){
+		Process p = null;
+		int ret = -1;
+
+		try{
+			String[] cmdOpenUrl = { "ssh", "-p", "2222", "root@localhost", "openURL", appName + ".app:/" };
+			p = Runtime.getRuntime().exec( cmdOpenUrl );
+			p.waitFor();
+
+			if( wait ){
+				ret = MobileUtil.getIOSProcessId( appName, true, launchTimeout );
+			}
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Kills a process which contains the given string in its name.
+	 **/
+	public static void killIOSApp( String appString ){
+		Process p = null;
+		int processId = -1;
+
+		try{
+			processId = MobileUtil.getIOSProcessId( appString, false );
+			killIOSApp( new Integer( processId ).intValue() );
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Kills a proces with a given process ID number.
+	 **/
+	public static void killIOSApp( int processId ){
+		Process p = null;
+
+		try{
+			String[] cmdStop = { "ssh", "-p", "2222", "root@localhost", "kill", Integer.toString( processId ) };
+			p = Runtime.getRuntime().exec( cmdStop );
+			p.waitFor();
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Removes an app.
+	 **/
+	public static void removeIOSApp( String appName ){
+		Process p = null;
+
+		try{
+			//System.out.println("Removing /User/Applications/" + appName + " if present");
+			String[] cmdRemoveApp = { "ssh", "-p", "2222", "root@localhost", "rm", "-r", "/User/Applications/" + appName };
+			p = Runtime.getRuntime().exec( cmdRemoveApp );
+			p.waitFor();
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Removes all apps in /var/mobile/Applications.
+	 **/
+	public static void removeAllIOSApps(){
+		Process p = null;
+
+		try{
+			String[] cmdRemoveApps = { "ssh", "-p", "2222", "root@localhost", "rm", "-r", "/User/Applications/*" };
+			p = Runtime.getRuntime().exec( cmdRemoveApps );
+			p.waitFor();
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Get the process id of the app on the device.
+	 * If wait = true, it will check every 500 ms until the process appears.  Be aware.
+	 * If wait = false, it will just check once.
+	 **/
+	public static int getIOSProcessId( String appName, boolean wait ){
+		return MobileUtil.getIOSProcessId( appName, wait, -1 );
+	}
+
+	public static int getIOSProcessId( String appName, boolean wait, long timeout ){
+		Process p = null;
+		boolean launchProcess = true;
+		boolean foundIt = false;
+		int ret = -1;
+		String line = "";
+		int i = 0;
+		long startTime = Calendar.getInstance().getTimeInMillis();
+		long curTime = 0;
+
+		try{
+
+			while( launchProcess ){
+				curTime = Calendar.getInstance().getTimeInMillis();
+
+				String[] cmdPS = { "ssh", "-p", "2222", "root@localhost", "ps", "-A" };
+				p = Runtime.getRuntime().exec( cmdPS );
+				line = MobileUtil.monitorProcessOutput( p, appName );
+				foundIt = (line != null);
+
+				if( !wait || foundIt ){
+					launchProcess = false;
+				}else if ( wait && (timeout > -1) && (curTime - startTime >= timeout) ){
+					launchProcess = false;
+				}else{
+					Thread.sleep(500);
+				}
+
+				// If we got a line, it will look like "   448 ??         0:33.90 /var/mobile/Applications/iconButtonTester/iconButtonTester.app/iconButtonTester"
+				// The first token which is a number is the process ID.
+				if( foundIt ){
+					if( line.trim().compareTo( "" ) != 0 ){
+						String[] chunks = line.split( " " );
+
+						for(i = 0; i < chunks.length; ++i){
+							try{
+								ret = new Integer( chunks[i] ).intValue();
+								break;
+							}catch(Exception e){
+							}
+						}
+					}
+				}
+			}
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+		return ret;
+	}
+
+	/**
+	 * Call ls via ssh.
+	 * Returns a string with information about the file, or null if not found.
+	 **/
+	public static String findIOSFile( String filename ){
+		Process p = null;
+		String ret = null;
+
+		try{
+			String[] cmdLS = { "ssh", "-p", "2222", "root@localhost", "ls", "-l", "--time-style=full-iso", filename };
+			p = Runtime.getRuntime().exec( cmdLS );
+			ret = MobileUtil.monitorProcessOutput( p, filename );
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Looks for the given string in the given file.
+	 * Returns true if found, false if not.
+	 **/
+	public static boolean searchIOSFile( String findMe, String filename ){
+		Process p = null;
+		boolean ret = false;
+
+		try{
+			String[] cmdCat = { "ssh", "-p", "2222", "root@localhost", "cat", filename };
+			p = Runtime.getRuntime().exec( cmdCat );
+			ret = ( MobileUtil.monitorProcessOutput( p, findMe ) != null );
+		}catch(Exception e){
+			e.printStackTrace();
+			ret = false;
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Given a process and a string, monitors the output of the
+	 * process for the string.  Returns the line in which
+	 * the string is found, or null if not found.
+	 * It will continue until the process exits.
+	 **/
+	public static String monitorProcessOutput( Process p, String theString ){
+		boolean keepReadingLines = true;
+		boolean endOfLine = false;
+		boolean foundIt = false;
+		boolean appRunning = true;
+		String ret = null;
+		int readInt = -1;
+		InputStream is = null;
+		BufferedReader br = null;
+		String line = "";
+
+		try{
+			//System.out.println("monitorProcessOutput: theString=" + theString);
+
+			is = p.getInputStream();
+			br = new BufferedReader( new InputStreamReader( is ) );
+
+			while( keepReadingLines ){
+				//System.out.println("monitorProcessOutput: reading lines");
+
+				endOfLine = false;
+				line = "";
+
+				while( !endOfLine ){
+					//System.out.println("monitorProcessOutput: reading a line");
+
+					if( br.ready() && (is.available() > 0) ){
+						readInt = is.read();
+
+						// We get 13 & 10 as end of line.
+						if( readInt == 13 || readInt == 10 ){
+							endOfLine = true;
+						}else{
+							line += (char)readInt;
+						}
+					}else{
+						Thread.sleep(100);
+						if( !processRunning(p) && (!br.ready()) && (is.available() <= 0) ){
+							// There's nothing else to do.  Bail.
+							endOfLine = true;
+							keepReadingLines = false;
+						}else{
+							//System.out.println("monitorProcessOutput: not bailing yet");
+						}
+					}
+				}
+				//System.out.println("monitorProcessOutput: line=" + line);
+
+				// At this point, we might have a line.
+				//System.out.println("\t\t" + line);
+				if( line.indexOf( theString ) > -1 ){
+					//System.out.println("monitorProcessOutput: found our line");
+					ret = line;
+					foundIt = true;
+					keepReadingLines = false;
+				}
+			}
+			//System.out.println("monitorProcessOutput: done reading lines");
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+
+		//System.out.println("monitorProcessOutput: returning " + ret);
+		return ret;
+	}
+
+	/**
+	 * Returns whether a process is running.
+	 * exitValue() throws an exception if the process
+	 * is still running.
+	 **/
+	public static boolean processRunning(Process p){
+		try{
+			int exitVal = p.exitValue();
+			return false;
+		}catch(IllegalThreadStateException e){
+			return true;
+		}
+	}
+
+	/**
+	 * Removes a file or directory from the device.
+	 **/
+	public static void removeIOSFile( String target ){
+		Process p = null;
+		File file = null;
+
+		if( findIOSFile( target ) != null ){
+			try{
+				System.out.println("Removing " + target);
+				String[] cmdRemove = { "ssh", "-p", "2222", "root@localhost", "rm", "-r", target };
+				p = Runtime.getRuntime().exec( cmdRemove );
+				p.waitFor();
+
+				if( findIOSFile( target ) != null ){
+					System.out.println("Removal of " + target + " failed.  Maybe it wasn't present.");
+				}
+			}catch(Exception e){
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * getSizeFromLsLine() receives a line like:
+	 *		-rw-r--r-- 1 mobile mobile 16326 2011-01-06 14:08:27.000000000 -0800 /User/Applications/iconButtonTester/Documents/MustellaResults.txt
+	 * and returns the size.  So far, I don't see how to make the ls command return just the size.
+	 * To get seconds, ls is used like this: ls -l --time-style=full-iso
+	 **/
+	public static long getSizeFromLsLine( String line ){
+		String[] tokens = line.split( " " );
+		int i = 0;
+		long ret = -1L;
+
+		try{
+			for( i = 0; i < tokens.length; ++i ){
+				if( i == 4 ){
+					ret = new Long( tokens[ i ] ).longValue();
+				}
+			}
+		}catch( Exception e ){
+			e.printStackTrace();
+		}
+
+		return ret;
+	}
+
+
+	/**
+	 * getTimeFromLsLine() receives a line like:
+	 *		-rw-r--r-- 1 mobile mobile 16326 2011-01-06 14:08:27.000000000 -0800 /User/Applications/iconButtonTester/Documents/MustellaResults.txt
+	 * and returns the time (milliseconds).  So far, I don't see how to make the ls command return just the time.
+	 * To get seconds, ls is used like this: ls -l --time-style=full-iso
+	 **/
+	public static long getTimeFromLsLine( String line ){
+		long ret = -1L;
+		GregorianCalendar cal = null;
+		String dateBlock = null;
+		String timeBlock = null;
+		String[] tokens = line.split( " " );
+		int year = -1;
+		int month = -1;
+		int date = -1;
+		int hours = -1;
+		int minutes = -1;
+		int seconds = -1;
+		int i = 0;
+		int j = 0;
+
+		for( i = 0; i < tokens.length; ++i ){
+			if( tokens[ i ].indexOf( "-" ) > -1 ){
+
+				// It's one of the fields with dashes. See if it looks like a date.
+				String[] dateTokens = tokens[ i ].split( "-" );
+
+				if( dateTokens.length == 3 ){
+
+					for( j = 0; j < dateTokens.length; ++j ){
+						try{
+							if( j == 0 ){
+								year = new Integer( dateTokens[ j ] ).intValue();
+							}else if( j == 1 ){
+								month = new Integer( dateTokens[ j ] ).intValue();
+							}else{
+								date = new Integer( dateTokens[ j ] ).intValue();
+							}
+						}catch( Exception e ){
+							//System.out.println(dateTokens[j] + " is not a date");
+						}
+					}
+				}
+			}
+
+			// It didn't contain dashes, so let's look for a time.
+			if( tokens[ i ].indexOf( ":" ) > -1 ){
+				String[] timeTokens = tokens[ i ].split( ":" );
+
+				if( timeTokens.length == 3 ){
+
+					for( j = 0; j < timeTokens.length; ++j ){
+						try{
+							if( j == 0 ){
+								hours = new Integer( timeTokens[ j ] ).intValue();
+							}else if( j == 1 ){
+								minutes = new Integer( timeTokens[ j ] ).intValue();
+							}else if( j == 2 ){
+								String secondsToken = timeTokens[j].substring( 0, timeTokens[j].indexOf(".") );
+								seconds = new Integer( secondsToken ).intValue();
+							}
+						}catch( Exception e ){
+							//System.out.println(timeTokens[j] + " is not a time");
+						}
+					}
+				}
+			}
+		}
+
+		if( year > -1 && month > -1 && date > -1 && hours > -1 && minutes > -1 && seconds > -1 ){
+			//System.out.println("getTimeFromLsLine(): We think we have a date and time for the log. year=" + year + ", month=" + month + ", date=" + date + ", hours=" + hours + ", minutes=" + minutes + ", seconds=" + seconds);
+
+			cal = new GregorianCalendar( year, month, date, hours, minutes, seconds );
+			ret = cal.getTimeInMillis();
+
+			//System.out.println("getTimeFromLsLine(): getTimeInMillis() returned " + ret);
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Remove temporary packaging files from the dir given (at the swfs level).
+	 * e.g.:
+	 *	- AOTBuildOutput1086061381018907696.tmp (dir)
+	 *	- MobileButtonMain2_ipa (dir)
+	 *	- air48611378876425949.tmp (file)
+	 *	- non-aot496151823287214585.tmp (file)
+	 *	- apk647202451803245042.tmp (file)
+	 *	- All .ipa files
+	 *	- All .apk files
+	 * Don't call this until all packaging is done, since many threads can package at once.
+	 **/
+	public static void removeTempPackagingFiles( String cleanDir ){
+		File subFile = null;
+		File dir = new File( cleanDir );
+
+		try{
+			if( dir.exists() && dir.isDirectory() ){
+				File[] arrFiles = dir.listFiles();
+
+				for(int i = 0; i < arrFiles.length; ++i){
+					subFile = arrFiles[i];
+
+					if( subFile.isDirectory() ){
+						if  ( subFile.getName().indexOf( "AOTBuildOutput" ) == 0 ||
+							( subFile.getName().endsWith( "_ipa" ) ) ){
+								System.out.println("Deleting packaging temp file directory " + subFile.getCanonicalPath());
+								FileUtils.recursivelyDelete( subFile.getCanonicalPath() );
+						}
+					}else{
+						// airXXXXXXX.tmp
+						if( (subFile.getName().indexOf( "air" ) == 0) &&
+							(subFile.getName().endsWith( ".tmp" ) ) ){
+								System.out.println("Deleting packaging temp file " + subFile.getCanonicalPath());
+								subFile.delete();
+						}
+
+						// non-aotXXXXX.tmp
+						if( (subFile.getName().indexOf( "non-aot" ) == 0) &&
+						    (subFile.getName().endsWith( ".tmp" ) ) ){
+							System.out.println("Deleting packaging temp file " + subFile.getCanonicalPath());
+							subFile.delete();
+						}
+
+						// apkXXXXX.tmp
+						if( (subFile.getName().indexOf( "apk" ) == 0) &&
+						    (subFile.getName().endsWith( ".tmp" ) ) ){
+							System.out.println("Deleting packaging temp file " + subFile.getCanonicalPath());
+							subFile.delete();
+						}
+
+						// all .ipa, .apk, .bar
+						if( ( subFile.getName().endsWith( ".ipa" ) ) ||
+							( subFile.getName().endsWith( ".bar" ) ) ||
+ 						    ( subFile.getName().endsWith( ".apk" ) ) ){
+								System.out.println("Deleting packaging temp file " + subFile.getCanonicalPath());
+								subFile.delete();
+						}
+
+						// BARXXXXXXXX.tmp
+						if ( ( subFile.getName().indexOf( "BAR" ) == 0 ) &&
+							 ( subFile.getName().endsWith( "tmp" ) ) ) {
+							System.out.println("Deleting packaging temp file " + subFile.getCanonicalPath());
+							subFile.delete();
+						}
+					}
+				}
+			}
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+	}
+
+
+} // End class
+

Propchange: incubator/flex/trunk/mustella/java/src/utils/MobileUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/java/src/utils/MustellaDirs.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/java/src/utils/MustellaDirs.java?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/java/src/utils/MustellaDirs.java (added)
+++ incubator/flex/trunk/mustella/java/src/utils/MustellaDirs.java Wed May  2 22:44:38 2012
@@ -0,0 +1,422 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package utils;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Creates compile commands given a list of files, 
+ * basically: searches .mxml files for a testSWF="val" and
+ * returns the set of includes for that testSWF
+ * the assumption is that we're in the current directory to do the compile.
+ * descrube:
+ */
+public class MustellaDirs { 
+
+	public static final String testProp =  "testSWF=";
+
+	/**
+	 * find the testSWF and return what it references.
+	 */
+	public static String getTestSwf(String name) { 
+
+		String ret = null;
+
+		try { 
+
+			String line = null;
+			BufferedReader br = new BufferedReader (new FileReader (name));
+			/// we will not go far into a file to get this
+			int count = 0 ;
+
+			int loc = -1;
+
+			while ( (line=br.readLine()) != null) { 
+
+				if ((loc = line.indexOf(testProp)) != -1) {
+
+					ret = line.substring (loc+testProp.length()+1, line.indexOf ("\"", loc + testProp.length()+2));
+					break;
+
+				}
+			}
+
+		} catch (Exception e) { 
+			e.printStackTrace();
+		}
+
+
+
+		String dir = null;
+
+
+		if (ret != null)
+			dir=getSwfDir (name);
+
+		if (dir != null)
+			return dir + File.separator + ret;
+		else { 
+
+				
+			return ret;
+
+		}
+
+
+	}
+
+
+	public static String getSwfDir (String file) {
+
+
+		// bust off the back.
+
+		String dir = null;
+
+		dir = file.substring (0, file.lastIndexOf(File.separator));	
+		// System.out.println ("dir1: " + dir);
+		dir = dir.substring (0, dir.lastIndexOf(File.separator));	
+		// System.out.println ("dir1: " + dir);
+
+		
+		String copy1 = dir + File.separator + "SWFs";
+
+		// System.out.println ("TRYING: " + copy1);
+
+		if ( new File(copy1).exists()) {
+			// System.out.println ("FOUND IT!");
+			return copy1;
+		}
+
+
+		String copy2 = dir + File.separator + "swfs";
+		// System.out.println ("TRYING: " + copy2);
+
+		if ( new File(copy2).exists()) { 
+			// System.out.println ("FOUND IT!");
+			return copy2;
+		}
+		
+
+		return null;
+
+	}
+
+
+
+	public static void printAsCommands(HashMap hm) { 
+
+		// getCommands (hm);
+		
+		String test = null;
+		Iterator it = hm.entrySet().iterator();
+		Map.Entry me = null;
+		ArrayList tmp = null;
+		String tmps = null;
+		while (it.hasNext()) { 
+
+			me = (Map.Entry) it.next();
+			test= (String)me.getKey();
+			tmp = (ArrayList) me.getValue();
+
+			System.out.print (test);
+			System.out.print (" "); 
+
+			for (int i=0;i<tmp.size();i++) { 
+				System.out.print (tmp.get(i));
+				System.out.print (" "); 
+			}
+	
+			System.out.println (""); 
+		}		
+
+
+
+	}
+
+
+	public static void getCommands (HashMap hm) { 
+
+
+		Iterator it = hm.entrySet().iterator();
+		ArrayList ret = new ArrayList();
+		ArrayList tmp = null;
+
+
+		StringBuffer sb = null;
+		String test = null;
+		String tmps = null;
+
+		Map.Entry me = null;
+		while (it.hasNext()) { 
+
+			me = (Map.Entry) it.next();
+			test= (String)me.getKey();
+			tmp = (ArrayList) me.getValue();
+
+			ArrayList tmpr = new ArrayList();
+
+			if (tmp == null)
+				continue;
+
+			sb  = new StringBuffer();
+
+			for (int i=0;i<tmp.size();i++) { 
+				
+				sb.append (" -includes=");	
+				sb.append ( (String)tmp.get(i) );		
+				tmpr.add (sb.toString());
+				
+			}
+
+
+			hm.put (test, tmpr);
+
+		}
+		
+
+		// return ret;
+
+	}
+
+
+	public static boolean contains (String target, String toSplit) { 
+
+		String [] args = toSplit.split (";");
+
+
+		for (int i=0;i<args.length;i++) { 
+			if (args[i].equals (target)) { 
+				return true;
+			}
+		}
+
+		return false;
+
+		
+
+
+
+	}
+
+	/**
+	 the bug is that swfs maps testSwfs to fq path to testSwf
+
+	 but it could be a dupe in the test swf name, 
+
+	 which would fail. 
+	
+	**/
+
+	public static void genHashMap (String file, HashMap includes, HashMap swfs, String survivor) { 
+
+		if (!file.endsWith (".mxml"))
+			System.out.println ("not an mxml file, returning");
+
+
+		HashMap map = new HashMap ();
+
+		String testSwf = null;
+		testSwf = getTestSwf (file);
+
+
+		// System.out.println ("have this file and test swf: " + file + " " + testSwf);
+
+
+		ArrayList al = null;
+
+		Iterator it = null;
+
+		String tmp = null;
+
+		String path = null;
+
+		int count = 0;
+
+
+		/// It references a testSwf, ergo, it goes on the -include line
+		if (testSwf != null) { 
+			al = (ArrayList)includes.get (testSwf);
+			// first test seen for this swf
+			if (al == null) { 
+				/// create a list for the line
+				al = new ArrayList();
+				includes.put (testSwf, al);
+			}
+
+
+				
+			if (swfs.get (testSwf) == null) 
+				swfs.put (testSwf, null);
+
+			/// I think we'll have to clean this up
+			try { 
+				path = new File(file).getParent();
+				file = new File(file).getName();
+				/// if survivor is non null, we're only adding the file it points to
+				if (survivor != null)  { 
+					// if (file.equals (survivor))  { 
+					if (contains(file, survivor))  { 
+						// System.out.println ("genHash - survivor file: adding path, file: " + path + " " + file + " for key: " + testSwf);	
+						al.add (" -includes=" + cleanFile(file));
+						if (path != null && path.length() > 0) 
+							al.add (" -source-path+=" + path);
+					} 
+				} else { 
+					// System.out.println ("genHash - file: adding path, file: " + path + " " + file + " for key: " + testSwf);	
+					al.add (" -includes=" + cleanFile(file));
+				// this could get too long. We should really only add this once
+				// ie, get rid of duplicates
+					if (path != null && path.length() > 0) { 
+               			         al.add (" -source-path=" + path);
+					 // System.out.println ("genHash - Adding path: " + path);
+					} 
+					/* 
+					if (swfs.get (testSwf) == null) { 
+					 	System.out.println ("genHash - Still null for " + testSwf + " Making a guess" );
+						addGuessSwfPath (swfs, testSwf, path);
+					}	
+					*/
+				}
+			} catch (Exception e) { 
+				System.out.println ("Exception dealing with the path/Name there");
+				e.printStackTrace();
+			}
+		} else { 
+			/// in this half, we have an mxml file that does not reference 
+			/// a testswf itself, potentially.
+			/// let's yank the end of it off and figure out the key it goes with
+			/// swfs creates an association of simple names, like main.mxml, 
+			/// to their path + file name
+			tmp = new File ( file ).getPath() ;
+			// tmp = new File ( file ).getName() ;
+			// System.out.println ("genHash - file: non referent: "+ tmp + " " + file);
+			if ( swfs.get(tmp) == null) { 
+				// System.out.println ("genHash - file: non referent: "+ tmp + " " + file);
+				swfs.put (file, tmp);
+			} 
+		}
+
+		// System.out.println (swfs);
+
+	}
+
+
+	/**
+	 * make a guess about the right path + test swf
+	 */
+	public static void addGuessSwfPath (HashMap swfs, String testSwf, String path) { 
+
+
+		/// return the guess about where this stuff lives if it's not already there
+		try { 
+			testSwf = new File (testSwf).getName();
+			// System.out.println ("addGuess with tweaked testSwf: " + testSwf);
+			if (new File (transform1(testSwf, path)).exists()) { 
+				// System.out.println ("genHash - putting on a new swf for " + testSwf);
+			
+				swfs.put (testSwf, transform1(testSwf,path));
+			} 
+		} catch (NullPointerException npe) { 
+				System.out.println ("genHash - putting a null on for " + testSwf);
+				swfs.put (testSwf, null);
+
+		}
+
+
+	}
+
+
+	/**
+	 * walk the path to guess about the right path + test swf
+	 */
+	public static String transform1 (String file, String path) { 
+
+		// System.out.println ("genHash - transform with : " + file + " " + path);
+
+		if (path.indexOf (File.separator) != -1) { 
+			path = path.substring (0, path.lastIndexOf (File.separator));
+			// System.out.println ("path now: " + path);
+			if (new File(path + File.separator + "SWFs").exists()) { 
+				path=path + File.separator + "SWFs";
+			} else if (new File(path + File.separator + "swfs").exists()) {
+				path=path + File.separator + "swfs";
+			}
+			if (new File(path + File.separator + file).exists())
+				path=path + File.separator + file;
+			else { 
+				path = null;
+			}
+				
+		} else if (path.indexOf ("/") != -1) { 
+			path = path.substring (0, path.lastIndexOf ("/"));
+			// System.out.println ("path now: " + path);
+			if (new File(path + "/"+ "SWFs").exists()) { 
+				path=path + "/"+ "SWFs";
+			} else if (new File(path + "/"+ "swfs").exists()) { 
+				path=path + "/"+ "swfs";
+			}
+
+			if (new File(path + "/" + file).exists())
+				path=path + "/"+ file;
+			else { 
+				path = null;
+			}
+
+		}
+
+
+		return path ;
+
+	}
+
+	public static void printFiles (String dir) { 
+
+		try { 
+			System.out.println ("Begin list");
+
+			String [] s = new File (dir).list();
+
+			for (int i=0;i<s.length;i++) 
+				System.out.println (s[i]);
+
+			
+
+		} catch (Exception e) { 
+		}
+
+		System.out.println ("END list");
+	}
+
+
+	public static String cleanFile (String f) { 
+
+		if (f.indexOf (".mxml") != -1)
+			return f.substring (0, f.indexOf (".mxml"));
+
+		return f;
+
+
+	}
+	public static void main (String [] args) throws Exception { 
+
+
+	}
+
+}

Propchange: incubator/flex/trunk/mustella/java/src/utils/MustellaDirs.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message