Package flex2.compiler.mxml.builder

Source Code of flex2.compiler.mxml.builder.ArrayBuilder$ElementNodeHandler

/*
*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/

package flex2.compiler.mxml.builder;

import flex2.compiler.CompilationUnit;
import flex2.compiler.util.CompilerMessage.CompilerError;
import flex2.compiler.mxml.MxmlConfiguration;
import flex2.compiler.mxml.dom.*;
import flex2.compiler.mxml.lang.BindingHandler;
import flex2.compiler.mxml.lang.StandardDefs;
import flex2.compiler.mxml.lang.TextParser;
import flex2.compiler.mxml.lang.ValueNodeHandler;
import flex2.compiler.mxml.reflect.Assignable;
import flex2.compiler.mxml.reflect.Type;
import flex2.compiler.mxml.reflect.TypeTable;
import flex2.compiler.mxml.rep.Array;
import flex2.compiler.mxml.rep.BindingExpression;
import flex2.compiler.mxml.rep.Model;
import flex2.compiler.mxml.rep.MxmlDocument;
import flex2.compiler.util.NameFormatter;

import java.util.Collection;
import java.util.Iterator;

/**
* This builder handles building an Array instance from an ArrayNode
* and it's children.
*
* @author Clement Wong
*/
class ArrayBuilder extends AbstractBuilder
{
  ArrayBuilder(CompilationUnit unit, TypeTable typeTable, MxmlConfiguration mxmlConfiguration, MxmlDocument document)
  {
    this(unit, typeTable, mxmlConfiguration, document, null, null, true);
  }

  ArrayBuilder(CompilationUnit unit, TypeTable typeTable, MxmlConfiguration mxmlConfiguration, MxmlDocument document,
         Model parent, Assignable assignable, boolean allowBinding)
  {
    super(unit, typeTable, mxmlConfiguration, document);
    this.parent = parent;
    this.assignable = assignable;
    this.allowBinding = allowBinding;
  }

  private ElementNodeHandler elementNodeHandler = new ElementNodeHandler();
  private ElementBindingHandler elementBindingHandler = new ElementBindingHandler();

  private Model parent;
  private Assignable assignable;
  private boolean allowBinding;
  Array array;

  public void analyze(ArrayNode node)
  {
    createArrayModel(node.beginLine);
    processStateAttributes(node, array);
    ensureId(node);
    processChildren(node.getChildren());
    registerModel(node, array, parent == null);
  }

  /*
   * TODO should take array element type and use when processing text initializer, etc.
   */
  public void createArrayModel(int line)
  {
    array = new Array(document, parent, line, getElementType());
        array.setParentIndex(getName(), getStateName());
  }

  /**
   *
   */
  void createSyntheticArrayModel(int line)
  {
    createArrayModel(line);
  }
 
  /**
   *
   */
    private void ensureId(ArrayNode node)
    {
      String id = (String) getLanguageAttributeValue(node, StandardDefs.PROP_ID);
      if (id != null)
            array.setId(id, false);
    }
   
  /**
   *
   */
  void processChildren(Collection nodes)
  {
    CDATANode cdata = getTextContent(nodes, true);
    if (cdata != null)
    {
      processTextInitializer(cdata.image, typeTable.objectType, cdata.inCDATA, cdata.beginLine);
    }
    else
    {
      for (Iterator iter = nodes.iterator(); iter.hasNext(); )
      {
        elementNodeHandler.invoke(assignable, (Node)iter.next(), document);
      }
    }
  }

    private String getName()
    {
        return assignable != null ? assignable.getName() : null;
    }

    private String getStateName()
    {
        return assignable != null ? assignable.getStateName() : null;
    }

    private Type getElementType()
    {
        return assignable != null ? assignable.getElementType() :  typeTable.objectType;
    }

  /**
   *
   */
  protected class ElementNodeHandler extends ValueNodeHandler
  {
    protected void componentNode(Assignable property, Node node, MxmlDocument document)
    {
      ComponentBuilder builder = new ComponentBuilder(unit, typeTable, mxmlConfiguration, document, array, null, null, false, elementBindingHandler);
      node.analyze(builder);
      builder.component.setParentIndex(array.size());
      array.addEntry(builder.component);
    }

    protected void arrayNode(Assignable property, ArrayNode node)
    {
      ArrayBuilder builder = new ArrayBuilder(unit, typeTable, mxmlConfiguration, document, array, null, allowBinding);
      node.analyze(builder);
      builder.array.setParentIndex(array.size());
      array.addEntry(builder.array);
    }

        protected void vectorNode(Assignable property, VectorNode node)
        {
            String typeAttributeValue = (String) node.getAttribute(StandardDefs.PROP_TYPE).getValue();
            Type elementType = typeTable.getType(NameFormatter.toColon(typeAttributeValue));
            VectorBuilder builder = new VectorBuilder(unit, typeTable, mxmlConfiguration, document,
                                                      array, null, elementType, allowBinding);
            node.analyze(builder);
            builder.vector.setParentIndex(array.size());
            array.addEntry(builder.vector);
        }

    protected void primitiveNode(Assignable property, PrimitiveNode node)
    {
      PrimitiveBuilder builder = new PrimitiveBuilder(unit, typeTable, mxmlConfiguration, document, array, false, property, elementBindingHandler);
      node.analyze(builder);
      array.addEntry(builder.value);
    }

    protected void xmlNode(Assignable property, XMLNode node)
    {
      //  TODO why not support XML nodes as array elements?
      log(node, new ElementNotSupported(node.image));
    }
       
        protected void xmlListNode(Assignable property, XMLListNode node)
        {
            //  TODO why not support XMLLists nodes as array elements?
            log(node, new ElementNotSupported(node.image));
        }

    protected void modelNode(Assignable property, ModelNode node)
    {
      //  TODO why not support Model nodes as array elements?
      log(node, new ElementNotSupported(node.image));
    }

    protected void inlineComponentNode(Assignable property, InlineComponentNode node)
    {
      InlineComponentBuilder builder = new InlineComponentBuilder(unit, typeTable, mxmlConfiguration, document, false);
      node.analyze(builder);
      array.addEntry(builder.getRValue());
    }

    protected void reparentNode(Assignable property, ReparentNode node)
        {
            ComponentBuilder builder = new ComponentBuilder(unit, typeTable, mxmlConfiguration, document, array, null, null, false, null);
            node.analyze(builder);
            builder.component.setParentIndex(array.size());
            array.addEntry(builder.component);
        }

        protected void cdataNode(Assignable property, CDATANode node)
        {
            PrimitiveBuilder builder = new PrimitiveBuilder(unit, typeTable, mxmlConfiguration, document, array, false, property, elementBindingHandler);
            node.analyze(builder);
            array.addEntry(builder.value);
        }

        protected void stateNode(Assignable property, StateNode node)
        {
            ComponentBuilder builder = new ComponentBuilder(unit, typeTable, mxmlConfiguration, document, array, null, null, false, null);
            node.analyze(builder);
            builder.component.setParentIndex(array.size());
            array.addEntry(builder.component);
        }
       
    protected void unknown(Assignable property, Node node)
    {
      log(node, new UnknownNode(node.image));
    }
  }

  /**
   *
   */
  public void processTextInitializer(String text, Type arrayElementType, boolean cdata, int line)
  {
    int flags = cdata ? TextParser.FlagInCDATA : 0;
    Object result = textParser.parseValue(text, typeTable.arrayType, arrayElementType, flags, line, typeTable.arrayType.getName());

    if (result != null)
    {
      if (result instanceof BindingExpression)
      {
        if (allowBinding)
        {
          BindingExpression bindingExpression = (BindingExpression)result;
          if (parent != null)
          {
            bindingExpression.setDestination(parent);
          }
          else
          {
            bindingExpression.setDestination(array);
          }

          bindingExpression.setDestinationLValue(getName());
          bindingExpression.setDestinationProperty(getName());
        }
        else
        {
          log(line, new BindingNotAllowed());
        }
      }
      else
      {
        //  TODO for symmetry's sake, allow <Array>[a,b,c]</Array>. (Used to error.) Can yank.
        assert result instanceof Array;
        array.setEntries(((Array)result).getEntries());
      }
    }
  }

  /**
   * Note that we don't mind if dest == null. See comments in PrimitiveBuilder
   */
  protected class ElementBindingHandler implements BindingHandler
  {
    public BindingExpression invoke(BindingExpression bindingExpression, Model dest)
    {
      bindingExpression.setDestination(array);
      bindingExpression.setDestinationLValue(Integer.toString(array.size()));
      bindingExpression.setDestinationProperty(array.size());
      return bindingExpression;
    }
  }

    public static class ElementNotSupported extends CompilerError
    {
        private static final long serialVersionUID = 8466102389418978639L;
        public String image;

        public ElementNotSupported(String image)
        {
            this.image = image;
        }
    }

    public static class UnknownNode extends CompilerError
    {
        private static final long serialVersionUID = -3924881722877853113L;
        public String image;

        public UnknownNode(String image)
        {
            this.image = image;
        }
    }
}
TOP

Related Classes of flex2.compiler.mxml.builder.ArrayBuilder$ElementNodeHandler

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.