예제 #1
0
파일: Execution.java 프로젝트: gangeli/jeli
 public static void fillOptions(Properties props, String[] args) {
   // (convert to map)
   Map<String, String> options = new HashMap<String, String>();
   for (String key : props.stringPropertyNames()) {
     options.put(key, props.getProperty(key));
   }
   options.putAll(parseOptions(args));
   // (bootstrap)
   fillOptions(BOOTSTRAP_CLASSES, options, false); // bootstrap
   log.bootstrap();
   log.startTrack("init");
   // (fill options)
   Class<?>[] visibleClasses = getVisibleClasses(options); // get classes
   Map<String, Field> optionFields = fillOptions(visibleClasses, options); // fill
 }
예제 #2
0
파일: Execution.java 프로젝트: gangeli/jeli
 public static final ResultLogger getLogger() {
   if (logger == null) {
     log.warn(LOG_TAG, "In-memory logging only (log database options were not set?)");
     logger = new InMemoryLogger();
   }
   return logger;
 }
예제 #3
0
파일: Execution.java 프로젝트: gangeli/jeli
 protected static final void initDatabase(
     Class<?>[] classes, Map<String, String> options, Map<String, Field> optionFields) {
   if (outputDB == null) {
     return;
   }
   // --Init Database
   outputDB.connect();
   DBResultLogger logger = new DBResultLogger(outputDB, runName);
   Execution.logger = logger;
   outputDB.beginTransaction();
   // --Add Options
   for (String key : optionFields.keySet()) {
     Field f = optionFields.get(key.toLowerCase());
     // (try to save the declared option)
     String value = options.get(key);
     if (value == null) {
       // (if no declared option, get field value)
       try {
         boolean accessSave = true;
         if (!f.isAccessible()) {
           accessSave = false;
           f.setAccessible(true);
         }
         Object v = f.get(null);
         if (v == null) {
           value = "<null>";
         } else if (v.getClass().isArray()) {
           value = Arrays.toString((Object[]) v);
         } else {
           value = v.toString();
         }
         if (!accessSave) {
           f.setAccessible(false);
         }
       } catch (IllegalArgumentException e) {
         throw log.fail(e);
       } catch (IllegalAccessException e) {
         throw log.fail(e);
       }
     }
     logger.logOption(key, value, f.getDeclaringClass().getName() + "." + f.getName());
   }
   // --Commit
   outputDB.endTransaction();
 }
예제 #4
0
파일: Execution.java 프로젝트: gangeli/jeli
 @SuppressWarnings("rawtypes")
 private static final Class filePathToClass(String cpEntry, String path) {
   if (path.length() <= cpEntry.length()) {
     throw new IllegalArgumentException("Illegal path: cp=" + cpEntry + " path=" + path);
   }
   if (path.charAt(cpEntry.length()) != '/') {
     throw new IllegalArgumentException("Illegal path: cp=" + cpEntry + " path=" + path);
   }
   path = path.substring(cpEntry.length() + 1);
   path = path.replaceAll("/", ".").substring(0, path.length() - 6);
   try {
     return Class.forName(path, false, ClassLoader.getSystemClassLoader());
   } catch (ClassNotFoundException e) {
     throw log.fail("Could not load class at path: " + path);
   } catch (NoClassDefFoundError ex) {
     log.debug(LOG_TAG, "Class at path " + path + " is unloadable");
     return null;
   }
 }
예제 #5
0
파일: Execution.java 프로젝트: gangeli/jeli
 private static final void ensureScalaPath(Map<String, String> options, String[] cp) {
   // (check if it's in the classpath)
   try {
     Class.forName("scala.None", false, ClassLoader.getSystemClassLoader());
   } catch (ClassNotFoundException e) {
     // (case: scala library not in the classpath)
     if (options.containsKey(SCALA_PATH)) {
       // (case: scala_path option set)
       try {
         String path = options.get(SCALA_PATH);
         if (!(new File(path).exists())) {
           System.err.println("The library strongly integrates with the Scala runtime, ");
           System.err.println("however it could not find the Scala library (scala-library.jar) ");
           System.err.println(
               "at the path given by the command line option '" + SCALA_PATH + "': " + path);
           log.exit(ExitCode.BAD_OPTION);
         }
         URL url = new File(path).toURI().toURL();
         URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
         Class<URLClassLoader> sysclass = URLClassLoader.class;
         Method method = sysclass.getDeclaredMethod("addURL", url.getClass());
         boolean savedAccessible = method.isAccessible();
         method.setAccessible(true);
         method.invoke(sysloader, new Object[] {url});
         method.setAccessible(savedAccessible);
         Class.forName("scala.None", false, ClassLoader.getSystemClassLoader());
       } catch (Exception ex) {
         throw log.fail(ex);
       } // end try catch
     } else {
       // (case: we cannot find the scala library at all)
       System.err.println("The library strongly integrates with the Scala runtime, ");
       System.err.println(
           "however it could not find the Scala library (scala-library.jar) in the classpath, ");
       System.err.println("and the '" + SCALA_PATH + "' command line argument is not set.");
       log.exit(ExitCode.BAD_OPTION);
     }
   }
   options.remove(SCALA_PATH);
 }
예제 #6
0
파일: Execution.java 프로젝트: gangeli/jeli
 private static final void dumpOptions(Map<String, String> options) {
   StringBuilder b = new StringBuilder();
   for (String key : options.keySet()) {
     b.append("--").append(key).append(" \"").append(options.get(key)).append("\" \\\n");
   }
   try {
     File f = touch("options");
     if (f != null) {
       FileWriter w = new FileWriter(f);
       w.write(b.toString());
       w.close();
     }
   } catch (IOException e) {
     log.warn(LOG_TAG, "Could not write options file");
   }
 }
예제 #7
0
파일: Execution.java 프로젝트: gangeli/jeli
 public static void exec(Runnable toRun, String[] args, boolean exit, LogInterface logInterface) {
   // --Init
   log = logInterface;
   // (cleanup)
   ignoredClasspath = new String[0];
   runName = "<unnamed>";
   outputDB = null;
   dataDB = null;
   execDir = null;
   logger = null;
   // (bootstrap)
   Map<String, String> options = parseOptions(args); // get options
   fillOptions(BOOTSTRAP_CLASSES, options, false); // bootstrap
   log.bootstrap();
   log.startTrack("init");
   // (fill options)
   Class<?>[] visibleClasses = getVisibleClasses(options); // get classes
   Map<String, Field> optionFields = fillOptions(visibleClasses, options); // fill
   try {
     initDatabase(visibleClasses, options, optionFields); // database
   } catch (DatabaseException e) {
     log.warn(LOG_TAG, e.getMessage());
   }
   dumpOptions(options); // file dump
   log.endTrack("init");
   log.setup();
   // --Run Program
   try {
     log.startTrack("main");
     toRun.run();
     log.endTrack("main"); // ends main
     log.startTrack("flushing");
     if (logger != null) {
       logger.save();
     }
   } catch (Throwable e) { // catch everything
     log.exception(e);
     System.err.flush();
     if (logger != null) {
       exitMessage = e.getClass().getName() + ": " + e.getMessage();
       logger.suggestFlush(); // not a save!
     }
     log.exit(ExitCode.FATAL_EXCEPTION);
   }
   log.endTrack("flushing");
   if (exit) {
     log.exit(ExitCode.OK); // soft exit
   }
 }
예제 #8
0
파일: Execution.java 프로젝트: gangeli/jeli
  @SuppressWarnings("rawtypes")
  protected static final Map<String, Field> fillOptions(
      Class<?>[] classes, Map<String, String> options, boolean ensureAllOptions) {

    // --Get Fillable Options
    Map<String, Field> canFill = new HashMap<String, Field>();
    Map<String, Marker> required = new HashMap<String, Marker>();
    Map<String, String> interner = new HashMap<String, String>();
    for (Class c : classes) {
      Field[] fields = null;
      try {
        fields = c.getDeclaredFields();
      } catch (Throwable e) {
        log.debug(
            LOG_TAG,
            "Could not check fields for class: "
                + c.getName()
                + "  (caused by "
                + e.getClass()
                + ": "
                + e.getMessage()
                + ")");
        continue;
      }

      for (Field f : fields) {
        Option o = f.getAnnotation(Option.class);
        if (o != null) {
          // (check if field is static)
          if ((f.getModifiers() & Modifier.STATIC) == 0) {
            log.err(LOG_TAG, "Option can only be applied to static field: " + c + "." + f);
            System.exit(ExitCode.BAD_OPTION.code);
          }
          // (required marker)
          Marker mark = null;
          if (o.required()) {
            mark = new Marker();
            mark.unset();
          }
          // (add main name)
          String name = o.name().toLowerCase();
          if (name.equals("")) {
            name = f.getName().toLowerCase();
          }
          if (canFill.containsKey(name)) {
            String name1 =
                canFill.get(name).getDeclaringClass().getCanonicalName()
                    + "."
                    + canFill.get(name).getName();
            String name2 = f.getDeclaringClass().getCanonicalName() + "." + f.getName();
            if (!name1.equals(name2)) {
              log.err(
                  LOG_TAG,
                  "Multiple declarations of option " + name + ": " + name1 + " and " + name2);
              System.exit(ExitCode.BAD_OPTION.code);
            } else {
              log.err(
                  LOG_TAG,
                  "Class is in classpath multiple times: "
                      + canFill.get(name).getDeclaringClass().getCanonicalName());
            }
          }
          canFill.put(name, f);
          if (mark != null) required.put(name, mark);
          interner.put(name, name);
          // (add alternate names)
          if (!o.alt().equals("")) {
            for (String alt : o.alt().split(" *, *")) {
              alt = alt.toLowerCase();
              if (canFill.containsKey(alt) && !alt.equals(name))
                throw new IllegalArgumentException(
                    "Multiple declarations of option "
                        + alt
                        + ": "
                        + canFill.get(alt)
                        + " and "
                        + f);
              canFill.put(alt, f);
              if (mark != null) required.put(alt, mark);
              interner.put(alt, name);
            }
          }
        }
      }
    }

    // --Fill Options
    for (String key : options.keySet()) {
      String rawKey = key;
      key = key.toLowerCase();
      // (get values)
      String value = options.get(rawKey);
      Field target = canFill.get(key);
      // (mark required option as fulfilled)
      Marker mark = required.get(key);
      if (mark != null) {
        mark.set();
      }
      // (fill the field)
      if (target != null) {
        // (case: declared option)
        fillField(target, value);
      } else if (ensureAllOptions) {
        // (case: undeclared option)
        // split the key
        int lastDotIndex = rawKey.lastIndexOf('.');
        if (lastDotIndex < 0) {
          log.err(LOG_TAG, "Unrecognized option: " + key);
          System.exit(ExitCode.BAD_OPTION.code);
        }
        String className = rawKey.substring(0, lastDotIndex);
        String fieldName = rawKey.substring(lastDotIndex + 1);
        // get the class
        Class clazz = null;
        try {
          clazz = ClassLoader.getSystemClassLoader().loadClass(className);
        } catch (Exception e) {
          log.err(LOG_TAG, "Could not set option: " + rawKey + "; no such class: " + className);
          System.exit(ExitCode.BAD_OPTION.code);
        }
        // get the field
        try {
          target = clazz.getField(fieldName);
        } catch (Exception e) {
          log.err(
              LOG_TAG,
              "Could not set option: "
                  + rawKey
                  + "; no such field: "
                  + fieldName
                  + " in class: "
                  + className);
          System.exit(ExitCode.BAD_OPTION.code);
        }
        fillField(target, value);
      }
    }

    // --Ensure Required
    boolean good = true;
    for (String key : required.keySet()) {
      if (!required.get(key).isSet()) {
        log.err(
            LOG_TAG,
            "Missing required option: "
                + interner.get(key)
                + "   <in class: "
                + canFill.get(key).getDeclaringClass()
                + ">");
        required.get(key).set(); // don't duplicate error messages
        good = false;
      }
    }
    if (!good) {
      System.exit(ExitCode.BAD_OPTION.code);
    }

    return canFill;
  }
예제 #9
0
파일: Execution.java 프로젝트: gangeli/jeli
  private static final Class<?>[] getVisibleClasses(Map<String, String> options) {
    // --Variables
    List<Class<?>> classes = new ArrayList<Class<?>>();
    // (get classpath)
    String pathSep = System.getProperty("path.separator");
    String[] cp = System.getProperties().getProperty("java.class.path", null).split(pathSep);
    // --Configuration
    ensureScalaPath(options, cp);
    // --Fill Options
    // (get classes)
    for (String entry : cp) {
      // (should skip?)
      if (entry.equals(".") || entry.trim().length() == 0) {
        continue;
      }
      boolean isIgnored = false;
      for (String pattern : ignoredClasspath) {
        if (entry.matches(pattern)) {
          log.debug(LOG_TAG, "Ignoring options in classpath element: " + entry);
          isIgnored = true;
          break;
        }
      }
      if (isIgnored) {
        continue;
      }
      // (no, don't skip)
      File f = new File(entry);
      if (f.isDirectory()) {
        // --Case: Files
        LazyFileIterator iter = new LazyFileIterator(f, ".*class$");
        while (iter.hasNext()) {
          // (get the associated class)
          Class<?> clazz = filePathToClass(entry, iter.next().getPath());
          if (clazz != null) {
            // (add the class if it's valid)
            classes.add(clazz);
          }
        }
      } else if (!isIgnored(entry)) {
        // --Case: Jar
        try {
          JarFile jar = new JarFile(f);
          Enumeration<JarEntry> e = jar.entries();
          while (e.hasMoreElements()) {
            // (for each jar file element)
            JarEntry jarEntry = e.nextElement();
            String clazz = jarEntry.getName();
            if (clazz.matches(".*class$")) {
              // (if it's a class)
              clazz = clazz.substring(0, clazz.length() - 6).replaceAll("/", ".");
              // (add it)
              try {
                classes.add(Class.forName(clazz, false, ClassLoader.getSystemClassLoader()));
              } catch (ClassNotFoundException ex) {
                throw Log.internal("Could not load class in jar: " + f + " at path: " + clazz);
              } catch (NoClassDefFoundError ex) {
                log.debug(LOG_TAG, "Could not scan class: " + clazz + " (in jar: " + f + ")");
              }
            }
          }
        } catch (IOException e) {
          throw log.fail("Could not open jar file: " + f + "(are you sure the file exists?)");
        }
      } else {
        // case: ignored jar
      }
    }

    return classes.toArray(new Class<?>[classes.size()]);
  }
예제 #10
0
파일: Execution.java 프로젝트: gangeli/jeli
 private static void fillField(Field f, String value) {
   try {
     // --Permissions
     boolean accessState = true;
     if (Modifier.isFinal(f.getModifiers())) {
       log.err(LOG_TAG, "Option cannot be final: " + f);
       System.exit(ExitCode.BAD_OPTION.code);
     }
     if (!f.isAccessible()) {
       accessState = false;
       f.setAccessible(true);
     }
     // --Set Value
     Object objVal = Utils.cast(value, f.getGenericType());
     if (objVal != null) {
       if (objVal.getClass().isArray()) {
         // (case: array)
         Object[] array = (Object[]) objVal;
         // error check
         if (!f.getType().isArray()) {
           log.err(
               LOG_TAG,
               "Setting an array to a non-array field. field: "
                   + f
                   + " value: "
                   + Arrays.toString(array)
                   + " src: "
                   + value);
           System.exit(ExitCode.BAD_OPTION.code);
         }
         // create specific array
         Object toSet = Array.newInstance(f.getType().getComponentType(), array.length);
         for (int i = 0; i < array.length; i++) {
           Array.set(toSet, i, array[i]);
         }
         // set value
         f.set(null, toSet);
       } else {
         // case: not array
         f.set(null, objVal);
       }
     } else {
       log.err(
           LOG_TAG, "Cannot assign option field: " + f + " value: " + value + "; invalid type");
       System.exit(ExitCode.BAD_OPTION.code);
     }
     // --Permissions
     if (!accessState) {
       f.setAccessible(false);
     }
   } catch (IllegalArgumentException e) {
     log.err(
         LOG_TAG,
         "Cannot assign option field: "
             + f.getDeclaringClass().getCanonicalName()
             + "."
             + f.getName()
             + " value: "
             + value
             + " cause: "
             + e.getMessage());
     System.exit(ExitCode.BAD_OPTION.code);
   } catch (IllegalAccessException e) {
     log.err(
         LOG_TAG,
         "Cannot access option field: "
             + f.getDeclaringClass().getCanonicalName()
             + "."
             + f.getName());
     System.exit(ExitCode.BAD_OPTION.code);
   } catch (Exception e) {
     log.err(
         LOG_TAG,
         "Cannot assign option field: "
             + f.getDeclaringClass().getCanonicalName()
             + "."
             + f.getName()
             + " value: "
             + value
             + " cause: "
             + e.getMessage());
     System.exit(ExitCode.BAD_OPTION.code);
   }
 }