adalid.core.AbstractExpression.java Source code

Java tutorial

Introduction

Here is the source code for adalid.core.AbstractExpression.java

Source

/*
 * Este programa es software libre; usted puede redistribuirlo y/o modificarlo bajo los terminos
 * de la licencia "GNU General Public License" publicada por la Fundacion "Free Software Foundation".
 * Este programa se distribuye con la esperanza de que pueda ser util, pero SIN NINGUNA GARANTIA;
 * vea la licencia "GNU General Public License" para obtener mas informacion.
 */
package adalid.core;

import adalid.commons.util.ThrowableUtils;
import adalid.core.enums.OperationKind;
import adalid.core.expressions.VariantX;
import adalid.core.interfaces.BooleanExpression;
import adalid.core.interfaces.CharacterExpression;
import adalid.core.interfaces.ComparisonX;
import adalid.core.interfaces.ConditionalX;
import adalid.core.interfaces.DataAggregateX;
import adalid.core.interfaces.DataArtifact;
import adalid.core.interfaces.Entity;
import adalid.core.interfaces.EntityExpression;
import adalid.core.interfaces.Expression;
import adalid.core.interfaces.NaryExpression;
import adalid.core.interfaces.NumericExpression;
import adalid.core.interfaces.OrderedPairX;
import adalid.core.interfaces.PersistentEntity;
import adalid.core.interfaces.Property;
import adalid.core.interfaces.RowsAggregateX;
import adalid.core.interfaces.ScalarX;
import adalid.core.interfaces.State;
import adalid.core.interfaces.TemporalExpression;
import adalid.core.sql.QueryJoin;
import adalid.core.sql.QueryTable;
import adalid.core.wrappers.ExpressionWrapper;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * @author Jorge Campins
 */
public abstract class AbstractExpression extends AbstractArtifact implements NaryExpression {

    private static final Logger logger = Logger.getLogger(Expression.class);

    private static final String EOL = "\n";

    private static final String TAB = "\t";

    /**
     *
     */
    private Class<?> _dataType;

    /**
     *
     */
    private Expression _parentExpression;

    /**
     *
     */
    private Field _foreignExpressionField;

    /**
     *
     */
    private boolean _finalised;

    public List<Operation> getInitialStateBusinessOperationsList() {
        List<Operation> list = new ArrayList<>();
        if (this instanceof State) {
            Entity declaringEntity = getDeclaringEntity();
            if (declaringEntity != null) {
                State state;
                for (Operation operation : declaringEntity.getBusinessOperationsList()) {
                    if (OperationKind.INSTANCE.equals(operation.getOperationKind())) {
                        for (Transition transition : operation.getTransitionsList()) {
                            if (transition != null) {
                                state = transition.getX();
                                if (this.equals(state) && !list.contains(operation)) {
                                    list.add(operation);
                                }
                            }
                        }
                    }
                }
            }
        }
        return list;
    }

    public List<Operation> getFinalStateBusinessOperationsList() {
        List<Operation> list = new ArrayList<>();
        if (this instanceof State) {
            Entity declaringEntity = getDeclaringEntity();
            if (declaringEntity != null) {
                State state;
                for (Operation operation : declaringEntity.getBusinessOperationsList()) {
                    if (OperationKind.INSTANCE.equals(operation.getOperationKind())) {
                        for (Transition transition : operation.getTransitionsList()) {
                            if (transition != null) {
                                state = transition.getY();
                                if (this.equals(state) && !list.contains(operation)) {
                                    list.add(operation);
                                }
                            }
                        }
                    }
                }
            }
        }
        return list;
    }

    /**
     *
     */
    //  private Map<String, Expression> _expressions = new LinkedHashMap<>();
    //
    //  /**
    //   * @return the expressions
    //   */
    //  public List<Expression> getExpressionsList() {
    //      List<Expression> list = new ArrayList<>();
    //      for (Expression value : _expressions.values()) {
    //          if (value != null) {
    //              list.add(value);
    //          }
    //      }
    //      return list;
    //  }
    //
    //  /**
    //   * @return the expressions
    //   */
    //  public Map<String, Expression> getExpressionsMap() {
    //      return _expressions;
    //  }
    //
    /**
     * @return the data type
     */
    @Override
    public Class<?> getDataType() {
        return _dataType;
    }

    /**
     * @param dataType the type to set
     */
    protected void setDataType(Class<?> dataType) {
        _dataType = dataType;
    }

    /**
     * @return the parent expression
     */
    @Override
    public Expression getParentExpression() {
        return _parentExpression;
    }

    /**
     * @param parentExpression the parent expression to set
     */
    private void setParentExpression(Expression parentExpression) {
        if (parentExpression == null || getDeclaringArtifact() == null) {
            _parentExpression = parentExpression;
            AbstractExpression childExpression;
            Object[] operands = getOperands();
            if (operands != null) {
                for (Object operand : operands) {
                    if (operand instanceof AbstractExpression) {
                        childExpression = (AbstractExpression) operand;
                        childExpression.setParentExpression(this);
                    }
                }
            }
        }
    }

    /**
     * @return the foreign expression field
     */
    public Field getForeignExpressionField() {
        return _foreignExpressionField;
    }

    /**
     * @param foreignExpressionField the foreign expression field to set
     */
    protected void setForeignExpressionField(Field foreignExpressionField) {
        _foreignExpressionField = foreignExpressionField;
    }

    /**
     * @return the foreign expression name
     */
    public String getForeignExpressionName() {
        return _foreignExpressionField == null ? null : _foreignExpressionField.getName();
    }

    /**
     * @return the foreign expression type
     */
    public Class<?> getForeignExpressionType() {
        return _foreignExpressionField == null ? null : _foreignExpressionField.getDeclaringClass();
    }

    /**
     * @return the referenced columns list
     */
    @Override
    public List<Property> getReferencedColumnsList() {
        return new ArrayList<>(getReferencedColumnsMap().values());
    }

    /**
     * @return the referenced columns map
     */
    @Override
    public Map<String, Property> getReferencedColumnsMap() {
        Map<String, Property> map = new LinkedHashMap<>();
        Property property;
        Expression expression;
        Object[] operands = getOperands();
        if (operands != null) {
            for (Object operand : operands) {
                if (operand instanceof Property) {
                    property = (Property) operand;
                    map.put(property.getPathString(), property);
                } else if (operand instanceof Expression) {
                    expression = (Expression) operand;
                    map.putAll(expression.getReferencedColumnsMap());
                }
            }
        }
        return map;
    }

    /**
     * @return the referenced joins list
     */
    @Override
    public List<QueryJoin> getReferencedJoinsList() {
        return new ArrayList<>(getReferencedJoinsMap().values());
    }

    /**
     * @param queryTable
     * @return the referenced joins list
     */
    @Override
    public List<QueryJoin> getReferencedJoinsList(QueryTable queryTable) {
        return new ArrayList<>(getReferencedJoinsMap(queryTable).values());
    }

    /**
     * @return the referenced joins map
     */
    @Override
    public Map<String, QueryJoin> getReferencedJoinsMap() {
        Entity declaringEntity = getDeclaringEntity();
        if (declaringEntity instanceof PersistentEntity) {
            PersistentEntity pent = (PersistentEntity) declaringEntity;
            QueryTable queryTable = pent.getQueryTable();
            return getReferencedJoinsMap(queryTable);
        }
        return new LinkedHashMap<>();
    }

    /**
     * @param queryTable
     * @return the referenced joins map
     */
    @Override
    public Map<String, QueryJoin> getReferencedJoinsMap(QueryTable queryTable) {
        List<Property> columns = getReferencedColumnsList();
        return queryTable.getReferencedJoinsMap(columns);
    }

    Set<String> crossReferencedExpressionsSet;

    /**
     * @return the referenced expressions map
     */
    @Override
    public Set<String> getCrossReferencedExpressionsSet() {
        return getCrossReferencedExpressionsSet(getDeclaringEntity());
    }

    /**
     * @param declaringEntity
     * @return the referenced expressions map
     */
    @Override
    public Set<String> getCrossReferencedExpressionsSet(Entity declaringEntity) {
        if (crossReferencedExpressionsSet == null) {
            crossReferencedExpressionsSet = new LinkedHashSet<>();
            if (declaringEntity != null) {
                Object[] operands = getOperands();
                if (operands != null) {
                    Expression expression;
                    Entity expressionDeclaringEntity;
                    String key;
                    for (Object operand : operands) {
                        if (operand instanceof Primitive) {
                            continue;
                        }
                        if (operand instanceof Expression) {
                            expression = (Expression) operand;
                            expressionDeclaringEntity = expression.getDeclaringEntity();
                            if (expressionDeclaringEntity == null
                                    || expressionDeclaringEntity.equals(declaringEntity)) {
                                crossReferencedExpressionsSet
                                        .addAll(expression.getCrossReferencedExpressionsSet(declaringEntity));
                            } else {
                                key = expression.getCrossReferencedExpressionsKey();
                                if (key != null) {
                                    crossReferencedExpressionsSet.add(key);
                                }
                            }
                        }
                    }
                }
            }
        }
        return crossReferencedExpressionsSet;
    }

    @Override
    public String getCrossReferencedExpressionsKey() {
        Entity declaringEntity = getDeclaringEntity();
        String key = declaringEntity == null ? null : declaringEntity.getRoot().getName() + "." + getName();
        return key;
    }

    @Override
    public boolean isCrossReferencedExpression() {
        return TLC.getProject().containsCrossReferencedExpression(this);
    }

    /**
     * @return true if is a TemporalExpression; otherwise false
     */
    @Override
    public boolean isSingleEntityExpression() {
        Entity declaringEntity = getDeclaringEntity();
        return declaringEntity != null && isSingleEntityExpression(declaringEntity);
    }

    /**
     * @param declaringEntity
     * @return true if is a TemporalExpression; otherwise false
     */
    @Override
    public boolean isSingleEntityExpression(Entity declaringEntity) {
        if (declaringEntity == null) {
            return false;
        } else {
            Object[] operands = getOperands();
            if (operands != null) {
                Expression expression;
                Entity expressionDeclaringEntity;
                for (Object operand : operands) {
                    if (operand instanceof Expression) {
                        if (operand instanceof RowsAggregateX) {
                            return false;
                        }
                        expression = (Expression) operand;
                        expressionDeclaringEntity = expression.getDeclaringEntity();
                        if (expressionDeclaringEntity == null
                                || expressionDeclaringEntity.equals(declaringEntity)) {
                            if (expression.isSingleEntityExpression(declaringEntity)) {
                                continue;
                            }
                        }
                        return false;
                    }
                }
            }
            return true;
        }
    }

    /**
     * @return true if is a BooleanExpression; otherwise false
     */
    public boolean isBooleanExpression() {
        return this instanceof BooleanExpression;
    }

    /**
     * @return true if is a CharacterExpression; otherwise false
     */
    public boolean isCharacterExpression() {
        return this instanceof CharacterExpression;
    }

    /**
     * @return true if is a EntityExpression; otherwise false
     */
    public boolean isEntityExpression() {
        return this instanceof EntityExpression;
    }

    /**
     * @return true if is a NumericExpression; otherwise false
     */
    public boolean isNumericExpression() {
        return this instanceof NumericExpression;
    }

    /**
     * @return true if is a TemporalExpression; otherwise false
     */
    public boolean isTemporalExpression() {
        return this instanceof TemporalExpression;
    }

    /**
     * @return true if is a ComparisonX; otherwise false
     */
    public boolean isComparisonExpression() {
        return this instanceof ComparisonX;
    }

    /**
     * @return true if is a ConditionalX; otherwise false
     */
    public boolean isConditionalExpression() {
        return this instanceof ConditionalX;
    }

    /**
     * @return true if is a DataAggregateX; otherwise false
     */
    public boolean isDataAggregateExpression() {
        return this instanceof DataAggregateX;
    }

    /**
     * @return true if is a OrderedPairX; otherwise false
     */
    public boolean isOrderedPairExpression() {
        return this instanceof OrderedPairX;
    }

    /**
     * @return true if is a RowsAggregateX; otherwise false
     */
    public boolean isRowsAggregateExpression() {
        return this instanceof RowsAggregateX;
    }

    /**
     * @return true if is a ScalarX; otherwise false
     */
    public boolean isScalarExpression() {
        return this instanceof ScalarX;
    }

    /**
     * @return true if is a TemporalExpression; otherwise false
     */
    public boolean isVariantExpression() {
        return this instanceof VariantX;
    }

    /**
     * @return the finalised indicator
     */
    @Override
    public boolean isFinalised() {
        return _finalised;
    }

    @Override
    public void finalise() {
        XS1.checkAccess();
        if (_finalised) {
            return;
        }
        _finalised = true;
        //      finaliseFields();
        setParentExpression(null);
    }

    protected void copyDataType(Object object) {
        setDataType(getObjectDataType(object));
    }

    protected Class<?> getObjectDataType(Object object) {
        if (object == null) {
            return Object.class;
        } else if (object instanceof DataArtifact) {
            DataArtifact artifact = (DataArtifact) object;
            return artifact.getDataType();
            //      } else if (object instanceof Instance) {
            //          Instance instance = (Instance) object;
            //          Object key = instance.getInstanceKeyValue();
            //          return key == null ? Instance.class : key.getClass();
        } else {
            return object.getClass();
        }
    }

    public Expression getForeignExpression() {
        if (_foreignExpressionField == null) {
            return null;
        }
        String errmsg = "failed to get foreign expression \"" + _foreignExpressionField + "\" at " + this;
        Class<?> declaringClass = _foreignExpressionField.getDeclaringClass();
        Entity declaringEntity = declaringClass == null ? null : getDeclaringEntity();
        Project declaringProject = declaringEntity == null ? null : declaringEntity.getDeclaringProject();
        Entity foreignEntity = declaringProject == null ? null : declaringProject.getEntity(declaringClass);
        if (foreignEntity == null) {
            logger.error(errmsg);
            logger.error(TAB + "foreign expression field declaring class = " + declaringClass);
            logger.error(TAB + "declaring entity = " + declaringEntity);
            logger.error(TAB + "declaring project = " + declaringProject);
            logger.error(TAB + "foreign entity = " + foreignEntity);
            TLC.getProject().getParser().increaseErrorCount();
        } else {
            try {
                Object foreignExpression = _foreignExpressionField.get(foreignEntity);
                if (foreignExpression instanceof Expression) {
                    return (Expression) foreignExpression;
                }
                logger.error(errmsg);
                logger.error(TAB + _foreignExpressionField + " = " + foreignExpression);
                TLC.getProject().getParser().increaseErrorCount();
            } catch (IllegalArgumentException | IllegalAccessException ex) {
                logger.error(errmsg, ThrowableUtils.getCause(ex));
                TLC.getProject().getParser().increaseErrorCount();
            }
        }
        return null;
    }
    //
    // <editor-fold defaultstate="collapsed" desc="finaliseFields">
    //  private void finaliseFields() {
    //      String name;
    //      Class<?> type;
    //      int modifiers;
    //      boolean expressionArray;
    //      boolean restricted;
    //      for (Field field : XS.getFields(getClass(), Expression.class)) { // getClass().getDeclaredFields()
    //          field.setAccessible(true);
    //          logger.trace(field.toString());
    //          name = field.getName();
    //          type = field.getType();
    //          expressionArray = type.equals(Object[].class) && field.isAnnotationPresent(ExpressionArray.class);
    //          if (!expressionArray && !Expression.class.isAssignableFrom(type)) {
    //              continue;
    //          }
    //          modifiers = field.getModifiers();
    //          restricted = Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers);
    //          if (restricted) {
    //              continue;
    //          }
    //          String errmsg = "failed to initialize field \"" + field + "\" at " + this;
    //          try {
    //              Object value = field.get(this);
    //              if (value == null) {
    //                  logger.debug(name + "==null");
    //              } else if (value instanceof Expression) {
    //                  finaliseExpression(field, (Expression) value);
    //              } else if (value instanceof Object[]) {
    //                  Object[] operands = (Object[]) value;
    //                  for (int i = 0; i < operands.length; i++) {
    //                      if (operands[i] instanceof Expression) {
    //                          finaliseExpression(field, (Expression) operands[i], i);
    //                      }
    //                  }
    //              }
    //          } catch (IllegalArgumentException ex) {
    //              logger.error(errmsg, ThrowableUtils.getCause(ex));
    //              TLC.getProject().getParser().increaseErrorCount();
    //          } catch (IllegalAccessException ex) {
    //              logger.error(errmsg, ThrowableUtils.getCause(ex));
    //              TLC.getProject().getParser().increaseErrorCount();
    //          }
    //      }
    //  }
    //
    // <editor-fold defaultstate="collapsed" desc="finaliseExpression">
    //  private void finaliseExpression(Field field, Expression expression) {
    //      String key = field.getName();
    //      if (_expressions.containsKey(key)) {
    //          return;
    //      }
    //      finaliseExpression(field, expression, -1);
    //      _expressions.put(key, expression);
    //  }
    //
    //  private void finaliseExpression(Field field, Expression expression, int index) {
    //      if (field == null || expression == null) {
    //          return;
    //      }
    //      String name = index < 0 ? field.getName() : field.getName() + "_" + index;
    //      if (expression.isNotDeclared()) {
    //          expression.setDeclared(name, this, field, index);
    //          if (expression != this) {
    //              expression.finalise();
    //          }
    //      }
    //  }
    // </editor-fold>
    // </editor-fold>

    /**
     * @return the default wrapper class
     */
    @Override
    public Class<? extends ExpressionWrapper> getDefaultWrapperClass() {
        return ExpressionWrapper.class;
    }

    // <editor-fold defaultstate="collapsed" desc="toString">
    @Override
    protected String fieldsToString(int n, String key, boolean verbose, boolean fields, boolean maps) {
        String tab = verbose ? StringUtils.repeat(" ", 4) : "";
        String fee = verbose ? StringUtils.repeat(tab, n) : "";
        String faa = " = ";
        String foo = verbose ? EOL : ", ";
        String string = super.fieldsToString(n, key, verbose, fields, maps);
        if (fields || verbose) {
            if (verbose) {
                string += fee + tab + "type" + faa + _dataType + foo;
                string += fee + tab + "parentExpression" + faa + _parentExpression + foo;
            }
        }
        return string;
    }
    // </editor-fold>

}