Package com.orange.wink.model

Source Code of com.orange.wink.model.GlobalObject

/*--------------------------------------------------------
* Copyright (c) 2011, The Dojo Foundation
* This software is distributed under the "Simplified BSD license",
* the text of which is available at http://www.winktoolkit.org/licence.txt
* or see the "license.txt" file for more details.
*--------------------------------------------------------*/

/**
*
*/
package com.orange.wink.model;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.orange.wink.Constants;
import com.orange.wink.ast.Ast;
import com.orange.wink.ast.AstNode;
import com.orange.wink.exception.WinkParseException;
import com.orange.wink.parse.ParserUtils;
import com.orange.wink.parse.objects.Call;
import com.orange.wink.parse.objects.DefineCall;
import com.orange.wink.parse.objects.ExprResultCall;
import com.orange.wink.parse.objects.Function;
import com.orange.wink.parse.objects.ParseObject;
import com.orange.wink.parse.objects.SetName;
import com.orange.wink.parse.objects.SetProp;
import com.orange.wink.util.Common;

/**
* @author Sylvain Lalande
*
*/
public class GlobalObject extends LiteralObject {
  /**
   *
   */
  private final Ast ast;
  /**
   *
   */
  private final Map<String, ScriptObject> globalNamespaces;
  /**
   *
   */
  private final String WINDOW = "window";
  /**
   *
   */
  private final String WINDOW_LOCATION = "location";
  /**
   *
   */
  private final String HTML_ELEMENT = "HTMLElement";
  /**
   *
   */
  private final String HTML_ELEMENT_PROTOTYPE = "prototype";

  /**
   * @param n
   */
  public GlobalObject(final Ast ast) {
    super(ast.getHead());
    this.ast = ast;

    namespace.setGlobalScope(true);
    setLineStart(node.getLineStart());
    setLineEnd(node.getLineEnd());

    globalNamespaces = new HashMap<String, ScriptObject>();
    globalNamespaces.put(WINDOW, null);
    globalNamespaces.put(WINDOW + "." + WINDOW_LOCATION, null);
    globalNamespaces.put(HTML_ELEMENT, null);
    globalNamespaces.put(HTML_ELEMENT + "." + HTML_ELEMENT_PROTOTYPE, null);
  }

  /**
   * @see com.orange.wink.model.LiteralObject#interpret()
   */
  @Override
  public void interpret() throws WinkParseException {
    super.interpret();
  }

  /**
   * @param po
   * @throws WinkParseException
   */
  @Override
  protected void interpretParseObject(final ParseObject po) throws WinkParseException {
    if (po instanceof Function && ((Function) po).isRootFunction()) {
      interpretRootFunction((Function) po);
    } else if (po instanceof ExprResultCall) {
      interpretExprResultCall((ExprResultCall) po);
    } else {
      super.interpretParseObject(po);
    }
  }

  /**
   * @return
   * @throws WinkParseException
   */
  @Override
  protected List<ParseObject> retrieveParseObjects() throws WinkParseException {
    final List<ParseObject> result = Common.newArrayList(5);
    result.addAll(super.retrieveParseObjects());
    result.addAll(getRootFunctions(node));
    result.addAll(getExprResultCall(node));

    Common.trimList(result);

    return result;
  }

  /**
   * @param headNode
   * @return
   * @throws WinkParseException
   */
  private List<Function> getRootFunctions(final AstNode headNode) throws WinkParseException {
    final List<Function> functions = Common.newArrayList(5);
    ParserUtils.getFunctions(headNode, functions);
    Common.trimList(functions);
    for (final Function f : functions) {
      f.setRootFunction(true);
    }
    return functions;
  }

  /**
   * @param func
   * @throws WinkParseException
   */
  private void interpretRootFunction(final Function func) throws WinkParseException {
    final FunctionObject soChild = (FunctionObject) ParserUtils.buildScriptObject(func, this);
    final String name = func.getNode().getFunctionName();
    final Namespace ns = Namespace.build(namespace, name);
    addComponent(name, soChild, this, ns);
    soChild.interpret();
  }

  /**
   * @param headNode
   * @throws WinkParseException
   */
  private List<ExprResultCall> getExprResultCall(final AstNode headNode) throws WinkParseException {
    final List<ExprResultCall> calls = Common.newArrayList(5);
    ParserUtils.getExprResultCall(headNode, calls);
    return calls;
  }

  /**
   * @param call
   * @throws WinkParseException
   */
  private void interpretExprResultCall(final ExprResultCall expr) throws WinkParseException {
    final Call call = expr.getCall();

    Namespace ns;
    ns = new Namespace();
    ns.appendNamespace(namespace);
    ns.appendNamespace(call.getNamespace());

    FunctionObject globalFunc;
    try {
      final ScriptObject so = resolveByNamespace(ns);
      if (!(so instanceof FunctionObject)) {
        return;
      }
      globalFunc = (FunctionObject) so;
    } catch (final WinkParseException e) {
      if (Constants.failOnUnresolvedNamespace) {
        throw new WinkParseException(ns + " not accessible in " + namespace + " - " + Ast.getPositionInfo(expr.getNode()), e);
      } else {
        System.err.println("WARN - " + ns + " not accessible in " + namespace + " - " + Ast.getPositionInfo(expr.getNode()) + " - " + e.getMessage());
        return;
      }
    }

    if (call instanceof DefineCall) {
      final Map<String, Namespace> argumentsMap = new HashMap<String, Namespace>();
      for (int i = 0; i < globalFunc.getParameters().size(); i++) {
        final String funcParam = globalFunc.getParameters().get(i);

        final Namespace nsc = new Namespace();
        nsc.addName(Constants.WINK_NAMESPACE);
        argumentsMap.put(funcParam, nsc);
      }

      final List<AstNode> childsGlobalFunc = globalFunc.getNode().getChilds();
      for (final AstNode cgf : childsGlobalFunc) {
        interpretCallSetProp(cgf, globalFunc, argumentsMap, true);
      }
    } else {
      if (globalFunc.getParameters().size() != call.getParameters().size()) {
        throw new WinkParseException("call arguments count does not match function parameter count [" + globalFunc + "]");
      }

      final Map<String, Namespace> argumentsMap = new HashMap<String, Namespace>();
      for (int i = 0; i < globalFunc.getParameters().size(); i++) {
        final String funcParam = globalFunc.getParameters().get(i);
        argumentsMap.put(funcParam, call.getParameters().get(i));
      }

      final List<AstNode> childsGlobalFunc = globalFunc.getNode().getChilds();
      for (final AstNode cgf : childsGlobalFunc) {
        interpretCallSetProp(cgf, globalFunc, argumentsMap, false);
      }
    }
  }

  /**
   * @param headNode
   * @param globalFunc
   * @param argumentsMap
   * @throws WinkParseException
   */
  private void interpretCallSetProp(final AstNode headNode, final FunctionObject globalFunc, final Map<String, Namespace> argumentsMap, final boolean includeSetName) throws WinkParseException {
    final List<String> localVars = globalFunc.getLocalVarNames();

    if (includeSetName) {
      final List<SetName> setnames = getSetName(headNode);
      for (final SetName stn : setnames) {
        if (!localVars.contains(stn.getBindName())) {
          interpretSetName(stn);
        }
      }
    }

    final List<SetProp> setprops = retrieveSetProp(headNode);

    for (final SetProp sp : setprops) {
      final Namespace spnsArg = sp.getNamespace();
      final String firstName = spnsArg.getNames().get(0);

      if (localVars.contains(firstName)) {
        // skip setprop on a local var
        continue;
      }

      // System.out.println("try to resolve = " + firstName + " in " +
      // spnsArg + " with " + argumentsMap);

      Namespace spns;
      if (argumentsMap.containsKey(firstName)) {
        spns = new Namespace();
        spns.appendNamespace(argumentsMap.get(firstName));
        for (int i = 1; i < spnsArg.getNames().size(); i++) {
          spns.addName(spnsArg.getNames().get(i));
        }
      } else {
        spns = spnsArg;
      }
      spns.resolveThisBy(globalFunc.getParent().getNamespace());

      final ScriptObject soChild = ParserUtils.buildScriptObject(sp.getValue(), globalFunc);
      ScriptObject so = null;
      try {
        so = resolveByNamespace(spns);

        final String name = sp.getProp();
        final Namespace ns = Namespace.build(spns, name);
        so.addComponent(name, soChild, this, ns);

        soChild.interpret();
      } catch (final WinkParseException e) {
        if (Constants.failOnUnresolvedNamespace) {
          throw new WinkParseException(spns + " not accessible in " + namespace + " - " + Ast.getPositionInfo(sp.getNode()), e);
        } else {
          System.err.println("WARN - " + spns + " not accessible in " + namespace + " - " + Ast.getPositionInfo(sp.getNode()) + " - " + e.getMessage());
        }
      }
    }
  }

  /**
   * @param gns
   * @return
   * @throws WinkParseException
   */
  public boolean resolveGlobalNamespace(final String gns) throws WinkParseException {
    if (globalNamespaces.containsKey(gns)) {
      if (globalNamespaces.get(gns) == null) {
        if (gns.equals(HTML_ELEMENT)) {
          addHtmlElement();
        } else if (gns.equals(HTML_ELEMENT + "." + HTML_ELEMENT_PROTOTYPE)) {
          addHtmlElementPrototype();
        } else if (gns.equals(WINDOW)) {
          addWindow();
        } else if (gns.equals(WINDOW + "." + WINDOW_LOCATION)) {
          addWindowLocation();
        }
        return true;
      } else {
        return false;
      }
    }
    return false;
  }

  /**
   * @throws WinkParseException
   */
  private void addWindow() throws WinkParseException {
    final Namespace ns = new Namespace();
    ns.addName(WINDOW);
    final LiteralObject window = new LiteralObject();
    window.setVirtual(true);
    window.setLineEnd(1);
    addComponent(ns.getLastName(), window, this, ns);
    globalNamespaces.put(ns.toString(), window);
  }

  /**
   * @throws WinkParseException
   */
  private void addWindowLocation() throws WinkParseException {
    if (globalNamespaces.get(WINDOW) == null) {
      addWindow();
    }

    final Namespace ns = new Namespace();
    ns.addName(WINDOW);
    ns.addName(WINDOW_LOCATION);
    final LiteralObject windowLocation = new LiteralObject();
    windowLocation.setVirtual(true);
    windowLocation.setLineEnd(1);
    globalNamespaces.get(WINDOW).addComponent(ns.getLastName(), windowLocation, this, ns);
    globalNamespaces.put(ns.toString(), windowLocation);
  }

  /**
   * @throws WinkParseException
   */
  private void addHtmlElement() throws WinkParseException {
    final Namespace ns = new Namespace();
    ns.addName(HTML_ELEMENT);
    final LiteralObject htmlElement = new LiteralObject();
    htmlElement.setVirtual(true);
    htmlElement.setLineEnd(1);
    addComponent(ns.getLastName(), htmlElement, this, ns);
    globalNamespaces.put(ns.toString(), htmlElement);
  }

  /**
   * @throws WinkParseException
   */
  private void addHtmlElementPrototype() throws WinkParseException {
    if (globalNamespaces.get(HTML_ELEMENT) == null) {
      addHtmlElement();
    }

    final Namespace ns = new Namespace();
    ns.addName(HTML_ELEMENT);
    ns.addName(HTML_ELEMENT_PROTOTYPE);
    final LiteralObject htmlElementPrototype = new LiteralObject();
    htmlElementPrototype.setVirtual(true);
    htmlElementPrototype.setLineEnd(1);
    globalNamespaces.get(HTML_ELEMENT).addComponent(ns.getLastName(), htmlElementPrototype, this, ns);
    globalNamespaces.put(ns.toString(), htmlElementPrototype);
  }

  /**
   * @see com.orange.wink.model.LiteralObject#getNamedType()
   */
  @Override
  public String getNamedType() {
    return "GlobalObject";
  }

  /**
   * @see com.orange.wink.model.LiteralObject#getDescription()
   */
  @Override
  public String getDescription() {
    final StringBuffer sb = new StringBuffer();
    sb.append(sourceName);
    return sb.toString();
  }

  /**
   * @see com.orange.wink.model.ScriptObject#getFunctions()
   */
  @Override
  public Map<String, FunctionObject> getFunctions() {
    if (parent == null) {
      return super.getFunctions();
    } else {
      return parent.getFunctions();
    }
  }

  /**
   * @see com.orange.wink.model.ScriptObject#getLiterals()
   */
  @Override
  public Map<String, LiteralObject> getLiterals() {
    if (parent == null) {
      return super.getLiterals();
    } else {
      return parent.getLiterals();
    }
  }

  /**
   * @see com.orange.wink.model.ScriptObject#getProperties()
   */
  @Override
  public Map<String, DefaultObject> getProperties() {
    if (parent == null) {
      return super.getProperties();
    } else {
      return parent.getProperties();
    }
  }

  /**
   * @return the ast
   */
  public Ast getAst() {
    return ast;
  }
}
TOP

Related Classes of com.orange.wink.model.GlobalObject

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.