/*
 * Launcher.java
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 
 */

import java.io.InputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Launcher {

  public static void main(String[] args) {
    if (args.length < 1) {
      System.err.println(
        "Usage: java Launcher <classpath-file> <main-class> [args]");
      System.exit(1);
    }
    String _classpathFilename = args[0];
    String _mainClassname = args[1];

   // System.out.println("####[Launcher] get Base Home Setting ..." );

    String _OWB_HOME = System.getProperty("OWB_HOME");
    if (_OWB_HOME == null) _OWB_HOME = "";
    
    String _ORA_HOME = System.getProperty("ORA_HOME");
    if (_ORA_HOME == null) _ORA_HOME = "";

    String _JDK_HOME = System.getProperty("JDK_HOME");
    if (_JDK_HOME == null) _JDK_HOME = "";

    String _OEM_HOME = System.getProperty("OEM_HOME");
    if (_OEM_HOME == null) _OEM_HOME = "";

    String _IAS_HOME = System.getProperty("IAS_HOME");
    if (_IAS_HOME == null) _IAS_HOME = "";

    // Is debugging?
    String _debug = System.getProperty("DEBUG");
    boolean _isDebug = false;
    if (_debug != null && _debug.equalsIgnoreCase("true")) _isDebug=true;
   
  /*
    System.out.println("####[Launcher]:  _OWB_HOME = " + _OWB_HOME );
    System.out.println("####[Launcher]:  _ORA_HOME = " + _ORA_HOME );
    System.out.println("####[Launcher]:  _JDK_HOME = " + _JDK_HOME );
    System.out.println("####[Launcher]:  _OEM_HOME = " + _OEM_HOME );
    System.out.println("####[Launcher]:  _IAS_HOME = " + _IAS_HOME );

    System.out.println("####[Launcher]:  Load classpath and set classloader..." );
  */

    try {
      File classpathFile = new File(_classpathFilename);
      if (!classpathFile.exists()) {
        System.err.println("Cannot find classpath file " + _classpathFilename);
        System.exit(1);
      }

      BufferedReader reader =
        new BufferedReader(new FileReader(classpathFile));
      ArrayList urlList = new ArrayList();
      StringBuffer classpath = new StringBuffer();
      while (true) {
        String line = reader.readLine();

        if (line == null) 
          break;
        else
          line = line.trim();

        if (line.startsWith("#") || line.length() ==0) continue;

        line = line.trim().replace('/', File.separator.toCharArray()[0] );
        
        //substitute variables:
        //System.out.println("####[Launcher]:  Before substitute:  line =" + line);
        if (line.startsWith("$OWB_HOME"))
          line = _OWB_HOME + line.substring(9);
        else if (line.startsWith("$ORA_HOME"))
          line = _ORA_HOME + line.substring(9);
        else if (line.startsWith("$JDK_HOME"))
          line = _JDK_HOME + line.substring(9);
        else if (line.startsWith("$OEM_HOME"))
          line = _OEM_HOME + line.substring(9);
        else if (line.startsWith("$IAS_HOME"))
          line = _IAS_HOME + line.substring(9);
        
        //System.out.println("####[Launcher]:  After substitute:  line =" + line);

        // check if file exists
        File path = new File( line);
        if (!path.exists()) {
          // yuhhuang: bug 10405806 comment out the error messages
          if (_isDebug) {
          if (line.endsWith(".jar"))
            System.out.println("####[Launcher]:  Error! Cannot find and load the jar file '" + line + "'. OWB application may not be launched due to this error.");
          else 
            System.out.println("####[Launcher]:  Error! Cannot find the directory '" + line + "' and the jar files under this directory. OWB application may not be launched due to this error.");
          }

          continue;
        }

        if (path.isDirectory()) {
          File[] jarFiles = path.listFiles(
            new FilenameFilter() {
              public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".jar");
              }
            });

          
          // add directory if it does not contain any jar files otherwise add
          // all jar files under the given directory into classpath
          int len = jarFiles.length;

          if (len > 0) {
            for (int i = 0; i < len; i++) {
              urlList.add(jarFiles[i].toURL());
              classpath.append(jarFiles[i]);
              classpath.append(File.pathSeparator);
            }
            continue;
          }
        }

        urlList.add(path.toURL());
        classpath.append(path);
        classpath.append(File.pathSeparator);
      }

      // System.out.println("####[Launcher]:  classpath = \n " + classpath.toString() );
      
      // set new java class path and class loader
     // System.out.println("####[Launcher]:  set new java class path and class loader ...");
      System.setProperty("java.class.path", classpath.toString());
      URL[] urls = new URL[urlList.size()];
      URLClassLoader urlLoader = new URLClassLoader((URL[]) urlList.toArray(urls));


    //  System.out.println("####[Launcher]:  launch actual class ...");
      int newlen = args.length - 2;
      String[] newargs = new String[newlen];
      System.arraycopy(args, 2, newargs, 0, newlen);
      Class mainClass =null;
      try {
        mainClass = urlLoader.loadClass(_mainClassname);
      }
      catch (Exception e) {
        e.printStackTrace();
      }

      if (mainClass==null) {
        System.out.println("**** dynamic classloader failed. try SystemClassloader... ");
        mainClass =  ClassLoader.getSystemClassLoader().loadClass(_mainClassname); 
        if (mainClass==null) {
           System.out.println("**** SystemClassloader failed. ");
        }
      }


      Thread.currentThread().setContextClassLoader(urlLoader);

      Class[] argClass = new Class[] { newargs.getClass() };
     // System.out.println("####[Launcher]: Complete setting of the java class path and class loader. Main programe starts... ");
      Method mainMethod = mainClass.getDeclaredMethod("main", argClass);
      mainMethod.invoke(null, new Object[] { newargs });
    } catch (Exception e) {
      e.printStackTrace();
      System.out.println(e.toString());	
      System.exit(1);
    }
  }

}
