All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gxp.compiler.base..svn.text-base.Conditional.svn-base Maven / Gradle / Ivy

Go to download

Google XML Pages (GXP) is a templating system used to generate XML/SGML markup (most often HTML).

The newest version!
/*
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed 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 com.google.gxp.compiler.base;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.gxp.compiler.alerts.SourcePosition;
import com.google.gxp.compiler.schema.Schema;

import java.util.*;

/**
 * A conditional {@code Expression}. The internal representation of
 * <gxp:cond> and <gxp:if> and their nested clauses.
 */
public class Conditional extends Expression {
  private final ImmutableList clauses;
  private final Expression elseExpression;

  /**
   * Every condition that has to be checked is a {@code Clause}.
   */
  public static class Clause extends AbstractNode {
    private final Expression predicate;
    private final Expression expression;

    public Clause(Node fromNode, Expression predicate, Expression expression) {
      this(fromNode.getSourcePosition(), fromNode.getDisplayName(), predicate,
           expression);
    }

    public Clause(SourcePosition sourcePosition, String displayName,
                  Expression predicate, Expression expression) {
      super(sourcePosition, displayName);
      this.predicate = Preconditions.checkNotNull(predicate);
      this.expression = Preconditions.checkNotNull(expression);
    }

    public Expression getPredicate() {
      return predicate;
    }

    public Expression getExpression() {
      return expression;
    }

    public Clause withExpression(Expression newExpression) {
      return (newExpression.equals(expression)) 
          ? this
          : new Clause(this, predicate, newExpression);
    }

    public boolean alwaysEquals(Clause that) {
      return predicate.alwaysEquals(that.predicate)
          && expression.alwaysEquals(that.expression);
    }

    @Override
    public boolean equals(Object that) {
      return (that instanceof Clause) && equals((Clause) that);
    }

    public boolean equals(Clause that) {
      return equalsAbstractNode(that)
          && predicate.equals(that.predicate)
          && expression.equals(that.expression);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(
        abstractNodeHashCode(),
        predicate,
        expression);
    }
  }

  public Conditional(Node fromNode, Schema schema,
                     List clauses, Expression elseExpression) {
    super(fromNode, schema);
    if (clauses.isEmpty()) {
      throw new IllegalArgumentException("At least one clause is required.");
    }
    if (schema != null) {
      for (Clause clause : clauses) {
        Schema clauseSchema = clause.getExpression().getSchema();
        if (!schema.allows(clauseSchema)) {
          throw new IllegalArgumentException(
              "Incompatible schemas: " + clauseSchema + " clause in "
              + schema + " conditional");
        }
      }
      if (!Objects.equal(schema, elseExpression.getSchema())) {
        throw new IllegalArgumentException(
            "Incompatible schemas: " + elseExpression.getSchema()
            + " else in " + schema + " conditional");
      }
    }
    this.clauses = ImmutableList.copyOf(clauses);
    this.elseExpression = Preconditions.checkNotNull(elseExpression);
  }

  public Conditional(Node fromNode, Schema schema,
                     Expression predicate, Expression expression,
                     Expression elseExpression) {
    this(fromNode, schema,
         createClauses(fromNode, predicate, expression),
         elseExpression);
  }

  private static List createClauses(Node fromNode,
                                            Expression predicate,
                                            Expression expression) {
    return ImmutableList.of(new Clause(fromNode, predicate, expression));
  }

  public Conditional withSchemaAndClauses(Schema newSchema,
                                          List newClauses,
                                          Expression newElseExpression) {
    return (Objects.equal(getSchema(), newSchema)
            && Iterables.elementsEqual(newClauses, clauses)
            && elseExpression.equals(newElseExpression))
        ? this
        : new Conditional(this, newSchema, newClauses, newElseExpression);
  }

  public List getClauses() {
    return clauses;
  }

  public Expression getElseExpression() {
    return elseExpression;
  }

  public Conditional withClauses(List newClauses,
                                 Expression newElseExpression) {
    return (Iterables.elementsEqual(newClauses, clauses)
            && elseExpression.equals(newElseExpression))
        ? this
        : new Conditional(this, getSchema(), newClauses, newElseExpression);
  }

  @Override
  public boolean alwaysEquals(Expression that) {
    if ((!(that instanceof Conditional))
        || (that.getSchema() == null)
        || !that.getSchema().equals(getSchema())) {
      return false;
    }

    Conditional thatConditional = (Conditional) that;

    List hisClauses = thatConditional.getClauses();
    if (clauses.size() != hisClauses.size()) {
      return false;
    }
    for (int i = 0; i < clauses.size(); i++) {
      if (!clauses.get(i).alwaysEquals(hisClauses.get(i))) {
        return false;
      }
    }
    return elseExpression.alwaysEquals(thatConditional.getElseExpression());
  }

  @Override
  public  T acceptVisitor(ExpressionVisitor visitor) {
    return visitor.visitConditional(this);
  }

  @Override
  public boolean equals(Object that) {
    return (that instanceof Conditional) && equals((Conditional) that);
  }

  public boolean equals(Conditional that) {
    return equalsExpression(that)
        && Iterables.elementsEqual(clauses, that.clauses)
        && elseExpression.equals(that.elseExpression);
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(
        expressionHashCode(),
        clauses,
        elseExpression);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy