JsContext.java :  » Scripting » jscombiner » net » leegorous » jsc » Java Open Source

Java Open Source » Scripting » jscombiner 
jscombiner » net » leegorous » jsc » JsContext.java
/**
 * 
 */
package net.leegorous.jsc;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Stack;

/**
 * @author leegorous
 * 
 */
public class JsContext {
  public static String LINE_BREAK = System.getProperty("line.separator");

  private JsContextManager manager;

  private JsNode hierarchy;

  private List list = new ArrayList();

  public JsContext(JsContextManager manager) {
    this.manager = manager;
  }

  public void buildHierarchy(String name) throws Exception {
    JsFile js = manager.getClazz(name);
    if (hierarchy == null) {
      JsNode tree = new JsNode(js);
      tree.setManager(manager);
      hierarchy = tree;
      tree.process();
    } else {
      JsNode tree = new JsNode();
      tree.setManager(manager);
      hierarchy.setParent(tree);
      tree.addChild(hierarchy);
      hierarchy = tree;

      hierarchy.addChild(js);
    }
  }

  public JsContextManager getContextManager() {
    return manager;
  }

  /**
   * @return the hierarchy
   */
  public JsNode getHierarchy() {
    return hierarchy;
  }

  /**
   * Get the merged scripts list. All scripts with dependencies and common
   * imports defined in configuration file.<br/>
   * <strong>Important</strong>: Invoke {@link #getList()} after loading
   * scripts with {@link #load(String)}
   * 
   * @return the list
   * @throws Exception
   */
  public List getList() throws Exception {
    Set cp = new HashSet();
    for (Iterator it = list.iterator(); it.hasNext();) {
      JsFile js = (JsFile) it.next();
      cp.add(js.getClasspath());
    }
    List cfgs = new ArrayList();
    for (Iterator it = cp.iterator(); it.hasNext();) {
      String p = (String) it.next();
      JsFile cfg = manager.getClasspathConfig(p);
      if (cfg != null)
        cfgs.add(cfg);
    }

    List commons = new ArrayList();
    for (Iterator it = cfgs.iterator(); it.hasNext();) {
      JsFile js = (JsFile) it.next();
      List imported = processImport(new Stack(), js);
      if (imported == null)
        imported = new ArrayList();
      commons = mergeList(commons, imported);
    }
    for (Iterator it = commons.iterator(); it.hasNext();) {
      JsFile js = (JsFile) it.next();
      if (list.contains(js))
        list.remove(js);
    }
    commons.addAll(list);
    return commons;
  }

  /**
   * Get the merged scripts content.<br/>
   * <strong>Important</strong>: Invoke {@link #getScriptsContent()} after
   * loading scripts with {@link #load(String)}
   * 
   * @return the merged scripts content
   * @throws Exception
   */
  public String getScriptsContent() throws Exception {
    List list = getList();
    StringBuffer buf = new StringBuffer();
    for (Iterator it = list.iterator(); it.hasNext();) {
      JsFile js = (JsFile) it.next();
      buf.append(JavaScriptDocument.readFile(js.getFile())).append(
          LINE_BREAK);
    }
    return buf.toString();
  }

  /**
   * Load the script
   * 
   * @param path
   * @throws Exception
   */
  public void load(String path) throws Exception {
    JsFile js = manager.getJs(path);
    Stack stack = new Stack();
    List scripts = processJs(stack, js);

    if (list == null) {
      list = scripts;
      return;
    }
    list = mergeList(list, scripts);
  }

  /**
   * Merge two ordered list
   * 
   * @param list1
   * @param list2
   * @return a merged list
   */
  protected List mergeList(List list1, List list2) {
    if (list1 == null || list2 == null) {
      throw new IllegalArgumentException("both list should not be null");
    }

    if (list1.size() == 0)
      return new ArrayList(list2);
    if (list2.size() == 0)
      return new ArrayList(list1);

    List result = new ArrayList();
    int start = 0;
    for (Iterator it = list1.iterator(); it.hasNext();) {
      Object obj = it.next();
      int idx = list2.indexOf(obj);
      if (idx > -1) {
        if (start > idx)
          throw new RuntimeException("unexpected order");
        for (; start <= idx; start++) {
          result.add(list2.get(start));
        }
      } else {
        result.add(obj);
      }
    }
    for (; start < list2.size(); start++) {
      result.add(list2.get(start));
    }
    return result;
  }

  protected List processImport(Stack stack, JsFile js) throws Exception {
    List result = new ArrayList();

    List imported = js.getImported();
    if (imported != null) {
      for (Iterator it = imported.iterator(); it.hasNext();) {
        String clazz = (String) it.next();
        List classes = manager.getJsClasses(clazz);

        for (Iterator it2 = classes.iterator(); it2.hasNext();) {
          JsFile j = (JsFile) it2.next();
          List cls = processJs(stack, j);
          result = mergeList(result, cls);
        }
      }
    }

    return result;
  }

  protected List processJs(Stack stack, JsFile js) throws Exception {
    List result = null;
    if (!stack.contains(js)) {
      stack.add(js);

      result = processImport(stack, js);
      if (result == null) {
        result = new ArrayList();
      }
      result.add(js);

      stack.pop();
    } else {
      if (stack.contains(js))
        throw new LoopedImportException("found " + js.getName()
            + " in dependency path " + stack);
    }
    return result;
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.