Package com.orange.wink.model

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

/*--------------------------------------------------------
* 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.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.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 abstract class ScriptObject implements ScriptElement {
  /**
   *
   */
  protected int lineStart = -1;
  /**
   *
   */
  protected int lineEnd = -1;
  /**
   *
   */
  protected int charStart = -1;
  /**
   *
   */
  protected int charEnd = -1;
  /**
   *
   */
  protected Namespace namespace;
  /**
   *
   */
  protected String sourceName;
  /**
   *
   */
  private boolean sourceActiveInFile = true;
  /**
   *
   */
  protected ScriptObject parent;
  /**
   *
   */
  protected ScriptObject linkedParent;

  /**
   *
   */
  private final Map<String, LiteralObject> literals;
  /**
   *
   */
  private final Map<String, FunctionObject> functions;
  /**
   *
   */
  private final Map<String, DefaultObject> properties;
  /**
   *
   */
  protected ScriptObject parentImpl;
  /**
   *
   */
  protected final List<ScriptObject> extensions;
  /**
   *
   */
  protected boolean isVirtual;
  /**
   *
   */
  protected AstNode node;

  public ScriptObject() {
    literals = new HashMap<String, LiteralObject>(0);
    functions = new HashMap<String, FunctionObject>(0);
    properties = new HashMap<String, DefaultObject>(0);
    extensions = Common.newArrayList(0);
    namespace = new Namespace();
    parent = null;
    isVirtual = false;
  }

  /**
   * @param n
   */
  public ScriptObject(final AstNode n) {
    this();
    node = n;
    lineStart = n.getLineStart();
    lineEnd = n.getLineEnd();
  }

  /**
   * @return
   * @throws WinkParseException
   */
  protected List<ParseObject> retrieveParseObjects() throws WinkParseException {
    final List<ParseObject> result = Common.newArrayList(1);
    result.addAll(getSetName(getNode()));
    result.addAll(retrieveSetProp(getNode()));
    Common.trimList(result);
    return result;
  }

  /**
   * @throws WinkParseException
   */
  public void interpret() throws WinkParseException {
    final List<ParseObject> objects = retrieveParseObjects();

    Collections.sort(objects, ParseObject.getLineComparator());
    Collections.sort(objects, ParseObject.getTypeComparator());

    for (final ParseObject po : objects) {
      interpretParseObject(po);
    }
  }

  /**
   * @param po
   * @throws WinkParseException
   */
  protected void interpretParseObject(final ParseObject po) throws WinkParseException {
    if (po instanceof SetName) {
      interpretSetName((SetName) po);
    } else if (po instanceof SetProp) {
      interpretSetProp((SetProp) po);
    } else {
      throw new WinkParseException("ERROR - cannot interpret ParseObject : type not managed : " + po.getClass().getName());
    }
  }

  /**
   * @return
   */
  protected ScriptObject getCallThisReference() {
    return this;
  }

  /**
   * @param headNode
   * @throws WinkParseException
   */
  protected List<SetName> getSetName(final AstNode headNode) throws WinkParseException {
    final List<SetName> setnames = Common.newArrayList(1);
    ParserUtils.getSetName(headNode, setnames);
    Common.trimList(setnames);
    return setnames;
  }

  /**
   * @param sn
   * @throws WinkParseException
   */
  protected void interpretSetName(final SetName sn) throws WinkParseException {
    final String name = sn.getBindName();
    final ParseObject value = sn.getValue();
    final ScriptObject so = ParserUtils.buildScriptObject(value, this);
    final Namespace ns = Namespace.build(namespace, name);
    addComponent(name, so, this, ns);

    so.interpret();
  }

  /**
   * @param headNode
   * @return
   * @throws WinkParseException
   */
  protected List<SetProp> retrieveSetProp(final AstNode headNode) throws WinkParseException {
    final List<SetProp> setprops = Common.newArrayList(1);
    ParserUtils.getSetProp(headNode, setprops);
    Common.trimList(setprops);
    return setprops;
  }

  /**
   * @param sp
   * @throws WinkParseException
   */
  protected void interpretSetProp(final SetProp sp) throws WinkParseException {
    final Namespace spns = sp.getNamespace();
    spns.resolveThisBy(namespace);
    final ScriptObject soChild = ParserUtils.buildScriptObject(sp.getValue(), this);
    ScriptObject so;
    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 name
   * @param so
   * @param linkedParent
   * @param ns
   * @throws WinkParseException
   */
  public void addComponent(final String name, final ScriptObject so, final ScriptObject linkedParent, final Namespace ns) throws WinkParseException {
    so.setParent(this);
    so.setLinkedParent(linkedParent);
    so.setNamespace(ns);

    if (so instanceof FunctionObject) {
      addFunction(name, so);
      ((FunctionObject) so).populateParams();
    } else if (so instanceof LiteralObject) {
      addLiteral(name, so);
    } else if (so instanceof DefaultObject) {
      addProperty(name, so);
    }
  }

  /**
   * @param name
   * @param so
   * @throws WinkParseException
   */
  public void addLiteral(final String name, final ScriptObject so) throws WinkParseException {
    String key = name;
    final LiteralObject lo = (LiteralObject) so;
    if (getLiterals().containsKey(name)) {
      final LiteralObject pImpl = getLiterals().get(name);
      pImpl.addExtension(lo);
      key = name + pImpl.getExtendKey(lo);
    }
    getLiterals().put(key, lo);
  }

  /**
   * @param name
   * @param so
   * @throws WinkParseException
   */
  public void addFunction(final String name, final ScriptObject so) throws WinkParseException {
    String key = name;
    final FunctionObject fo = (FunctionObject) so;
    if (getFunctions().containsKey(name)) {
      final FunctionObject pImpl = getFunctions().get(name);
      pImpl.addExtension(fo);
      key = name + pImpl.getExtendKey(fo);
    }
    getFunctions().put(key, fo);
  }

  /**
   * @param name
   * @param so
   */
  public void addProperty(final String name, final ScriptObject so) {
    getProperties().put(name, (DefaultObject) so);
  }

  /**
   * @param ext
   * @return
   * @throws WinkParseException
   */
  public String getExtendKey(final ScriptObject ext) throws WinkParseException {
    int idx = -1;
    for (int i = 0; i < extensions.size(); i++) {
      if (extensions.get(i) == ext) {
        idx = i;
        break;
      }
    }
    if (idx == -1) {
      throw new WinkParseException("extended function not found in extensions");
    }
    return ".extend." + (idx + 1);
  }

  /**
   * @param fo
   */
  public void addExtension(final ScriptObject fo) {
    extensions.add(fo);
    fo.setParentImpl(this);
  }

  /**
   * @param ns
   * @return
   * @throws WinkParseException
   */
  public ScriptObject resolveByNamespace(final Namespace ns) throws WinkParseException {
    ScriptObject cursor = getGlobalScope();
    if (!ns.equals(cursor.getNamespace())) {
      for (final String name : ns.getNames()) {
        final Map<String, ScriptObject> sos = new HashMap<String, ScriptObject>();
        sos.putAll(cursor.getLiterals());
        sos.putAll(cursor.getFunctions());
        sos.putAll(cursor.getProperties());

        if (!sos.containsKey(name)) {
          final GlobalObject go = getGlobalScope();
          if (go.resolveGlobalNamespace(ns.toString())) {
            return resolveByNamespace(ns); // retry
          } else {
            throw new WinkParseException("resolveByNamespace failed: " + ns.toString() + " is not accessible");
          }
        }
        cursor = sos.get(name);
        final List<ScriptObject> exts = cursor.getExtensions();
        if (exts.size() > 0) {
          cursor = exts.get(exts.size() - 1);
        }
      }
    }
    return cursor;
  }

  /**
   * @return
   */
  public GlobalObject getGlobalScope() {
    final ScriptObject p = getLinkedParent();
    if (p == null) {
      if (this instanceof GlobalObject) {
        return (GlobalObject) this;
      }
      return null;
    } else if (p instanceof GlobalObject) {
      return (GlobalObject) p;
    } else {
      return p.getGlobalScope();
    }
  }

  /**
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    final StringBuffer sb = new StringBuffer();
    sb.append(namespace);
    sb.append(" [").append(getNamedType());
    if (parent != null) {
      sb.append(" extends ").append(parent.namespace.toString());
    }
    sb.append("] ");

    String desc = "";
    try {
      desc = getDescription();
    } catch (final WinkParseException e) {

    }
    sb.append(desc);

    sb.append(" (");
    if (sourceName != null) {
      final String[] sp = sourceName.split("/");
      sb.append(sp[sp.length - 1]).append("; ");
    }
    if (lineStart != -1 || lineEnd != -1) {
      final String ls = (lineStart == -1) ? "?" : new Integer(lineStart).toString();
      final String le = (lineEnd == -1) ? "?" : new Integer(lineEnd).toString();
      sb.append("L:").append(ls).append("-").append(le).append(";");
    }
    if (charStart != -1 || charEnd != -1) {
      final String cs = (charStart == -1) ? "?" : new Integer(charStart).toString();
      final String ce = (charEnd == -1) ? "?" : new Integer(charEnd).toString();
      sb.append("C:").append(cs).append("-").append(ce).append(";");
    }
    sb.append(")");
    return sb.toString();
  }

  /**
   * @param sb
   * @param level
   * @return
   */
  public String toStringRecursive(StringBuffer sb, final int level) {
    if (sb == null) {
      sb = new StringBuffer();
    }

    final String tab = "  ";
    final StringBuffer buf = new StringBuffer();
    for (int i = 0; i < level; i++) {
      buf.append(tab);
    }
    buf.append("[").append(level).append("] ");
    final String tabs = buf.toString();
    sb.append(tabs).append(toString());
    sb.append("\n");

    Set<String> keys = getLiterals().keySet();
    for (final String key : keys) {
      final ScriptObject so = getLiterals().get(key);
      so.toStringRecursive(sb, level + 1);
    }
    keys = getFunctions().keySet();
    for (final String key : keys) {
      final ScriptObject so = getFunctions().get(key);
      so.toStringRecursive(sb, level + 1);
    }

    keys = getProperties().keySet();
    for (final String key : keys) {
      final ScriptObject so = getProperties().get(key);
      so.toStringRecursive(sb, level + 1);
    }

    return sb.toString();
  }

  /**
   * @return
   */
  public ScriptObject getParent() {
    return parent;
  }

  /**
   * @param parent
   */
  public void setParent(final ScriptObject parent) {
    this.parent = parent;
  }

  /**
   * @return
   */
  public ScriptObject getLinkedParent() {
    return linkedParent;
  }

  /**
   * @param linkedParent
   */
  public void setLinkedParent(final ScriptObject linkedParent) {
    this.linkedParent = linkedParent;
  }

  /**
   * @return
   */
  public int getLineStart() {
    return lineStart;
  }

  /**
   * @param lineStart
   */
  public void setLineStart(final int lineStart) {
    this.lineStart = lineStart;
  }

  /**
   * @return
   */
  public int getLineEnd() {
    return lineEnd;
  }

  /**
   * @param lineEnd
   */
  public void setLineEnd(final int lineEnd) {
    this.lineEnd = lineEnd;
  }

  /**
   * @return
   */
  public int getCharStart() {
    return charStart;
  }

  /**
   * @param charStart
   */
  public void setCharStart(final int charStart) {
    this.charStart = charStart;
  }

  /**
   * @return
   */
  public int getCharEnd() {
    return charEnd;
  }

  /**
   * @param charEnd
   */
  public void setCharEnd(final int charEnd) {
    this.charEnd = charEnd;
  }

  /**
   * @return
   */
  public Namespace getNamespace() {
    return namespace;
  }

  /**
   * @param namespace
   */
  public void setNamespace(final Namespace namespace) {
    this.namespace = namespace;
  }

  /**
   * @return
   */
  public String getSourceName() {
    return sourceName;
  }

  /**
   * @param sourceName
   */
  public void setSourceName(final String sourceName) {
    this.sourceName = sourceName;
  }

  /**
   * @return
   */
  public Map<String, LiteralObject> getLiterals() {
    return literals;
  }

  /**
   * @return
   */
  public Map<String, FunctionObject> getFunctions() {
    return functions;
  }

  /**
   * @return
   */
  public Map<String, DefaultObject> getProperties() {
    return properties;
  }

  /**
   * @param parentImpl
   *            the parentImpl to set
   */
  public void setParentImpl(final ScriptObject parentImpl) {
    this.parentImpl = parentImpl;
  }

  /**
   * @return the isVirtual
   */
  public boolean isVirtual() {
    return isVirtual;
  }

  /**
   * @param isVirtual
   *            the isVirtual to set
   */
  public void setVirtual(final boolean isVirtual) {
    this.isVirtual = isVirtual;
  }

  /**
   * @return the extensions
   */
  public List<ScriptObject> getExtensions() {
    return extensions;
  }

  /**
   * @return the parentImpl
   */
  public ScriptObject getParentImpl() {
    return parentImpl;
  }

  /**
   * @return the sourceActiveInFile
   */
  public boolean isSourceActiveInFile() {
    return sourceActiveInFile;
  }

  /**
   * @param sourceActiveInFile
   *            the sourceActiveInFile to set
   */
  public void setSourceActiveInFile(final boolean sourceActiveInFile) {
    this.sourceActiveInFile = sourceActiveInFile;
  }

  /**
   * @return the node
   */
  @Override
  public AstNode getNode() {
    return node;
  }
}
TOP

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

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.