1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.javatest.batch;
  28 
  29 import java.io.File;
  30 import java.lang.NoSuchMethodException;
  31 import java.lang.reflect.Constructor;
  32 import java.lang.reflect.InvocationTargetException;
  33 import java.net.MalformedURLException;
  34 import java.net.URL;
  35 import java.net.URLClassLoader;
  36 import java.util.ListIterator;
  37 import java.util.Vector;
  38 
  39 import com.sun.javatest.Harness;
  40 import com.sun.javatest.tool.Command;
  41 import com.sun.javatest.tool.CommandContext;
  42 import com.sun.javatest.util.HelpTree;
  43 import com.sun.javatest.util.I18NResourceBundle;
  44 
  45 class ObserverCommand extends Command
  46 {
  47     static String getName() {
  48         return "observer";
  49     }
  50 
  51     static HelpTree.Node getHelp() {
  52         String[] opts = { "cp" };
  53         return new HelpTree.Node(i18n, "cmgr.help.observer", opts);
  54     }
  55 
  56     ObserverCommand(ListIterator<String> argIter) throws Fault {
  57         super(getName());
  58 
  59         Vector<String> v = null;
  60 
  61         while (argIter.hasNext()) {
  62             String arg = nextArg(argIter);
  63 
  64             if (arg.equals("-cp") && argIter.hasNext())
  65                 setClassPath(nextArg(argIter));
  66             else if (arg.startsWith("-"))
  67                 throw new Fault(i18n, "observer.badArg", arg);
  68             else {
  69                 className = arg;
  70                 while (argIter.hasNext()) {
  71                     arg = nextArg(argIter);
  72                     if (arg.equals("-end"))
  73                         break;
  74                     else {
  75                         if (v == null)
  76                             v = new Vector<>();
  77                         v.add(arg);
  78                     }
  79                 }
  80                 break;
  81             }
  82         }
  83 
  84         if (className == null)
  85             throw new Fault(i18n, "observer.noClassName");
  86 
  87         if (v != null) {
  88             classArgs = new String[v.size()];
  89             v.copyInto(classArgs);
  90         }
  91     }
  92 
  93     public void run(CommandContext ctx) throws Fault {
  94         try {
  95             Class<?> oc = loadClass(className);
  96 
  97             Harness.Observer o = null;
  98             if (classArgs == null || classArgs.length == 0) {
  99                 o = tryConstructor(oc,
 100                                    new Class<?>[] { },
 101                                    new Object[] { });
 102             }
 103             else if (classArgs.length == 1) {
 104                 o = tryConstructor(oc,
 105                                    new Class<?>[] { String.class },
 106                                    new Object[] { classArgs[0] });
 107             }
 108 
 109             if (o == null)
 110                 o = tryConstructor(oc,
 111                                    new Class<?>[] { String[].class },
 112                                    new Object[] { classArgs });
 113 
 114             if (o == null)
 115                 throw new Fault(i18n, "observer.cantFindConstructor", className);
 116 
 117             ctx.addHarnessObserver(o);
 118         }
 119         catch (ClassNotFoundException e) {
 120             throw new Fault(i18n, "observer.cantFindClass", className);
 121         }
 122         catch (IllegalAccessException e) {
 123             throw new Fault(i18n, "observer.cantAccessClass", className);
 124         }
 125         catch (InstantiationException e) {
 126             throw new Fault(i18n, "observer.cantCreateClass", className);
 127         }
 128         catch (InvocationTargetException e) {
 129             throw new Fault(i18n, "observer.cantCreateClass", className);
 130         }
 131     }
 132 
 133     private Harness.Observer tryConstructor(Class<?> obsClass, Class<?>[] argTypes, Object[] args)
 134         throws IllegalAccessException, InstantiationException, InvocationTargetException
 135     {
 136         try {
 137             Constructor<?> c = obsClass.getConstructor(argTypes);
 138             return (Harness.Observer) (c.newInstance(args));
 139         }
 140         catch (NoSuchMethodException e) {
 141             return null;
 142         }
 143     }
 144 
 145     private void setClassPath(String s) throws Fault {
 146         char pathCh = File.pathSeparatorChar;
 147         Vector<URL> v = new Vector<>();
 148         int start = 0;
 149         for (int i = s.indexOf(pathCh); i != -1; i = s.indexOf(pathCh, start)) {
 150             addClassPathEntry(s.substring(start, i), v);
 151             start = i + 1;
 152         }
 153         addClassPathEntry(s.substring(start), v);
 154         URL[] path = new URL[v.size()];
 155         v.copyInto(path);
 156         setClassPath(path);
 157     }
 158 
 159     private void setClassPath(URL[] path) {
 160         classLoader = new URLClassLoader(path);
 161     }
 162 
 163     private Class<?> loadClass(String name) throws ClassNotFoundException {
 164         return (classLoader == null ? Class.forName(name) : classLoader.loadClass(name));
 165     }
 166 
 167     private void addClassPathEntry(String s, Vector<URL> v) throws Fault {
 168         try {
 169             if (s.length() > 0)
 170                 v.add(new File(s).toURL());
 171         }
 172         catch (MalformedURLException e) {
 173             throw new Fault(i18n, "observer.badClassPath", new Object[] { s, e });
 174         }
 175     }
 176 
 177     private ClassLoader classLoader;
 178     private String className;
 179     private String[] classArgs;
 180 
 181     private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(BatchManager.class);
 182 }