Exemplo n.º 1
0
  private String[] loadPlugin(String name, String pluginSpec, String[] cmdArgs) {
    assert (_communicator != null);

    //
    // We support the following formats:
    //
    // <class-name> [args]
    // <jar-file>:<class-name> [args]
    // <class-dir>:<class-name> [args]
    // "<path with spaces>":<class-name> [args]
    // "<path with spaces>:<class-name>" [args]
    //

    String[] args;
    try {
      args = com.zeroc.IceUtilInternal.Options.split(pluginSpec);
    } catch (com.zeroc.IceUtilInternal.Options.BadQuote ex) {
      throw new PluginInitializationException(
          "invalid arguments for plug-in `" + name + "':\n" + ex.getMessage());
    }

    assert (args.length > 0);

    final String entryPoint = args[0];

    final boolean isWindows = System.getProperty("os.name").startsWith("Windows");
    boolean absolutePath = false;

    //
    // Find first ':' that isn't part of the file path.
    //
    int pos = entryPoint.indexOf(':');
    if (isWindows) {
      final String driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
      if (pos == 1
          && entryPoint.length() > 2
          && driveLetters.indexOf(entryPoint.charAt(0)) != -1
          && (entryPoint.charAt(2) == '\\' || entryPoint.charAt(2) == '/')) {
        absolutePath = true;
        pos = entryPoint.indexOf(':', pos + 1);
      }
      if (!absolutePath) {
        absolutePath = entryPoint.startsWith("\\\\");
      }
    } else {
      absolutePath = entryPoint.startsWith("/");
    }

    if ((pos == -1 && absolutePath) || (pos != -1 && entryPoint.length() <= pos + 1)) {
      //
      // Class name is missing.
      //
      throw new PluginInitializationException(
          "invalid entry point for plug-in `" + name + "':\n" + entryPoint);
    }

    //
    // Extract the JAR file or subdirectory, if any.
    //
    String classDir = null; // Path name of JAR file or subdirectory.
    String className;

    if (pos == -1) {
      className = entryPoint;
    } else {
      classDir = entryPoint.substring(0, pos).trim();
      className = entryPoint.substring(pos + 1).trim();
    }

    //
    // Shift the arguments.
    //
    String[] tmp = new String[args.length - 1];
    System.arraycopy(args, 1, tmp, 0, args.length - 1);
    args = tmp;

    //
    // Convert command-line options into properties. First we
    // convert the options from the plug-in configuration, then
    // we convert the options from the application command-line.
    //
    Properties properties = _communicator.getProperties();
    args = properties.parseCommandLineOptions(name, args);
    cmdArgs = properties.parseCommandLineOptions(name, cmdArgs);

    //
    // Instantiate the class.
    //
    PluginFactory pluginFactory = null;
    try {
      Class<?> c = null;

      //
      // Use a class loader if the user specified a JAR file or class directory.
      //
      if (classDir != null) {
        try {
          if (!absolutePath) {
            classDir =
                new java.io.File(System.getProperty("user.dir") + java.io.File.separator + classDir)
                    .getCanonicalPath();
          }

          if (!classDir.endsWith(java.io.File.separator)
              && !classDir.toLowerCase().endsWith(".jar")) {
            classDir += java.io.File.separator;
          }
          classDir = URLEncoder.encode(classDir, "UTF-8");

          //
          // Reuse an existing class loader if we have already loaded a plug-in with
          // the same value for classDir, otherwise create a new one.
          //
          ClassLoader cl = null;

          if (_classLoaders == null) {
            _classLoaders = new java.util.HashMap<>();
          } else {
            cl = _classLoaders.get(classDir);
          }

          if (cl == null) {
            final java.net.URL[] url =
                new java.net.URL[] {new java.net.URL("file", null, classDir)};

            //
            // Use the custom class loader (if any) as the parent.
            //
            if (_instance.initializationData().classLoader != null) {
              cl = new java.net.URLClassLoader(url, _instance.initializationData().classLoader);
            } else {
              cl = new java.net.URLClassLoader(url);
            }

            _classLoaders.put(classDir, cl);
          }

          c = cl.loadClass(className);
        } catch (java.net.MalformedURLException ex) {
          throw new PluginInitializationException(
              "invalid entry point format `" + pluginSpec + "'", ex);
        } catch (java.io.IOException ex) {
          throw new PluginInitializationException(
              "invalid path in entry point `" + pluginSpec + "'", ex);
        } catch (java.lang.ClassNotFoundException ex) {
          // Ignored
        }
      } else {
        c = com.zeroc.IceInternal.Util.getInstance(_communicator).findClass(className);
      }

      if (c == null) {
        throw new PluginInitializationException("class " + className + " not found");
      }

      java.lang.Object obj = c.newInstance();
      try {
        pluginFactory = (PluginFactory) obj;
      } catch (ClassCastException ex) {
        throw new PluginInitializationException(
            "class " + className + " does not implement PluginFactory", ex);
      }
    } catch (IllegalAccessException ex) {
      throw new PluginInitializationException(
          "unable to access default constructor in class " + className, ex);
    } catch (InstantiationException ex) {
      throw new PluginInitializationException("unable to instantiate class " + className, ex);
    }

    //
    // Invoke the factory.
    //
    Plugin plugin = null;
    try {
      plugin = pluginFactory.create(_communicator, name, args);
    } catch (PluginInitializationException ex) {
      throw ex;
    } catch (Throwable ex) {
      throw new PluginInitializationException("exception in factory " + className, ex);
    }

    if (plugin == null) {
      throw new PluginInitializationException("failure in factory " + className);
    }

    PluginInfo info = new PluginInfo();
    info.name = name;
    info.plugin = plugin;
    _plugins.add(info);

    return cmdArgs;
  }