Package easysm.executors

Source Code of easysm.executors.Checker

package easysm.executors;

import java.util.Set;

import easysm.Constants;
import easysm.datatypes.Expr;
import easysm.datatypes.Name;
import easysm.datatypes.information.*;
import easysm.factories.SetFactory;
import easysm.stores.*;
import easysm.stores.Class;

/**
* @author Alessio Parma
*/
public class Checker
{
  private Set<Name> predefinedTypesNames = SetFactory.createSet(Name.class);
  private Main main;
 
  public Checker(Main main)
  {
    this.main = main;
   
    // Predefined types names
    predefinedTypesNames.add(Constants.BOOLEAN_NAME);
    predefinedTypesNames.add(Constants.INTEGER_NAME);
    predefinedTypesNames.add(Constants.REAL_NAME);
    predefinedTypesNames.add(Constants.STRING_NAME);
  }
 
  /*
   *
   * Class checkers
   *
   */
 
  public boolean canAdd(ClassInfo newClassInfo)
  {
    return !typeExists(newClassInfo.name());
  }
 
  public boolean canDelete(Class cl)
  {
    if (main.inputCD().context() != null && main.inputCD().context().equals(cl)) {
      main.inputCDError(Constants.CLASS_IS_CONTEXT);
      return false;
    }
    return !typeIsUsed(cl.name());
  }
 
  public boolean canUpdate(Class oldClass, ClassInfo newClassInfo)
  {
    Name newClassName = newClassInfo.name();
    if (oldClass.name().equals(newClassName)) {
      return true;
    }
    return !typeExists(newClassName);
  }
 
  private boolean classExists(Name className)
  {
    for (Class c : main.inputCD().classes()) {
      if (c.name().equals(className))
        return true;
    }
    return false;
  }
 
  /*
   *
   * Enumeration checkers
   *
   */
 
  public boolean canAdd(EnumerationInfo newEnumInfo)
  {
    if (typeExists(newEnumInfo.name())) {
      return false;
    }
    if (literalsAreRepeated(newEnumInfo.literalsInfo())) {
      main.inputCDError(Constants.REPEATED_LITERALS);
      return false;
    }
    return true;
  }
 
  public boolean canDelete(Enumeration en)
  {
    if (typeIsUsed(en.name())) {
      return false;
    }
    // return literalsAreUsed(en.literals());
    return true;
  }
 
  public boolean canUpdate(Enumeration oldEnum, EnumerationInfo newEnumInfo)
  {
    if (literalsAreRepeated(newEnumInfo.literalsInfo())) {
      main.inputCDError(Constants.REPEATED_LITERALS);
      return false;
    }
    Name newEnumName = newEnumInfo.name();
    if (oldEnum.name().equals(newEnumName)) {
      return true;
    }
    return !typeExists(newEnumName);
  }
 
  private boolean enumExists(Name enumName)
  {
    for (Enumeration e : main.inputCD().enums()) {
      if (e.name().equals(enumName))
        return true;
    }
    return false;
  }
 
  private boolean literalsAreRepeated(Set<LiteralInfo> literalsInfo)
  {
    if (literalsInfo == null) {
      return false;
    }
    Set<Name> literalsNames = SetFactory.createSet(Name.class);
    // We add the name of each literal to the set;
    // since it is a set, it will not add a name if
    // it is already in the set.
    for (LiteralInfo li : literalsInfo) {
      if (!literalsNames.add(li.name())) {
        return true;
      }
    }
    return false;
  }
 
  /**
   * A literal may be used in:
   * - Invariants
   * - Conditions and reactions
  
  private boolean literalsAreUsed(Set<Literal> literals)
  {
    StringBuilder invOccurences = new StringBuilder();
    StringBuilder crOccurences = new StringBuilder();
    for (Literal lit : literals) {
      invOccurences.append(occurencesInInvariants(lit));
      crOccurences.append(occurencesInCondsReacts(lit));
    }
    String invErrors = invOccurences.toString();
    String crErrors = crOccurences.toString();
    if (!(invErrors.isEmpty() && crErrors.isEmpty())) {
      invErrors = "* State observers:\n" + invErrors;
      crErrors = "* Events:\n" + crErrors;
      main.inputCDError(invErrors + crErrors);
      return true;
    }
    return false;
  }
 
  private String occurencesInInvariants(Literal lit)
  {
    Set<StateObserver> blockingSO = SetFactory.createSet(StateObserver.class);
    for (StateObserver currSO : main.stateObservers().stateObserverSet()) {
      if (currSO.invariant().contains(lit)) {
        blockingSO.add(currSO);
      }
    }
    return processOccurencesInInvariants(blockingSO);
  }
 
  private String occurencesInCondsReacts(Literal lit)
  {
    Set<Event> blockingEvents = SetFactory.createSet(Event.class);
    for (Event ev : main.events().eventSet()) {
      for (CondReact cr : ev.conditionsReactions()) {
        if (cr.cond().contains(lit)) {
          blockingEvents.add(ev);
          break;
        }
        if (cr.react().contains(lit)) {
          blockingEvents.add(ev);
          break;
        }
      }
    }
    return processOccurrencesInCondsReacts(blockingEvents);
  }*/
 
  /*
   *
   * Attribute checkers
   *
   */
 
  public boolean canAdd(AttributeInfo newAttrInfo)
  {
    Name newAttrName = newAttrInfo.name();
    Class container = (Class) newAttrInfo.ofClass();
    if (attrExists(newAttrName, container)) {
      main.inputCDError(Constants.EXISTING_ATTRIBUTE);
      return false;
    }
    return true;
  }
 
  public boolean canDelete(Attribute attr)
  {
    // return !attrIsUsed(attr);
    return true;
  }
 
  public boolean canUpdate(Attribute oldAttr, AttributeInfo newAttrInfo)
  {
    Name newAttrName = newAttrInfo.name();
    Class container = (Class) newAttrInfo.ofClass();
    if (!oldAttr.name().equals(newAttrName) && attrExists(newAttrName, container)) {
      main.inputCDError(Constants.EXISTING_ATTRIBUTE);
      return false;
    }
    return true;
  }
 
  private boolean attrExists(Name attrName, Class container)
  {
    for (Attribute a : container.attributes()) {
      if (a.name().equals(attrName))
        return true;
    }
    return false;
  }
 
  /**
   * An attribute may be used in:
   * - Invariants
   * - Conditions and reactions
  
  private boolean attrIsUsed(Attribute attr)
  {
    String invOccur = occurencesInInvariants(attr);
    String crOccur = occurencesInCondsReacts(attr);
    String errorString = invOccur + crOccur;
    if (!errorString.isEmpty()) {
      main.soError("* Attributes:\n" + errorString);
      return true;
    }
    return false;
  }
 
  private String occurencesInInvariants(Attribute attr)
  {
    Set<StateObserver> blockingSO = SetFactory.createSet(StateObserver.class);
    for (StateObserver currSO : main.stateObservers().stateObserverSet()) {
      if (currSO.invariant().contains(attr)) {
        blockingSO.add(currSO);
      }
    }
    return processOccurencesInInvariants(blockingSO);
  }
 
  private String occurencesInCondsReacts(Attribute attr)
  {
    Set<Event> blockingEvents = SetFactory.createSet(Event.class);
    for (Event ev : main.events().eventSet()) {
      for (CondReact cr : ev.conditionsReactions()) {
        if (cr.cond().contains(attr)) {
          blockingEvents.add(ev);
          break;
        }
        if (cr.react().contains(attr)) {
          blockingEvents.add(ev);
          break;
        }
      }
    }
    return processOccurrencesInCondsReacts(blockingEvents);
  }*/
 
  /*
   *
   * Operation checkers
   *
   */
 
  public boolean canAdd(OperationInfo newOpInfo)
  {
    Name newOpName = newOpInfo.name();
    Class container = (Class) newOpInfo.ofClass();
    if (opExists(newOpName, container)) {
      main.inputCDError(Constants.EXISTING_OPERATION);
      return false;
    }
    if (paramsAreRepeated(newOpInfo.parametersInfo())) {
      main.inputCDError(Constants.REPEATED_PARAMETERS);
      return false;
    }
    return true;
  }
 
  public boolean canDelete(Operation op)
  {
    // return !opIsUsed(op);
    return true;
  }
 
  public boolean canUpdate(Operation oldOp, OperationInfo newOpInfo)
  {
    Name newOpName = newOpInfo.name();
    Class container = (Class) newOpInfo.ofClass();
    if (!oldOp.name().equals(newOpName) && opExists(newOpName, container)) {
      main.inputCDError(Constants.EXISTING_OPERATION);
      return false;
    }
    if (paramsAreRepeated(newOpInfo.parametersInfo())) {
      main.inputCDError(Constants.REPEATED_PARAMETERS);
      return false;
    }
    return true;
  }
 
  private boolean opExists(Name opName, Class container)
  {
    for (Operation o : container.operations()) {
      if (o.name().equals(opName))
        return true;
    }
    return false;
  }
 
  /**
   * An operation may be used in:
   * - Invariants
   * - Conditions and reactions
  
  private boolean opIsUsed(Operation op)
  {
    String invOccur = occurencesInInvariants(op);
    String crOccur = occurencesInCondsReacts(op);
    String errorString = invOccur + crOccur;
    if (!errorString.isEmpty()) {
      main.soError("* Operations:\n" + errorString);
      return true;
    }
    return false;
  }
 
  private String occurencesInInvariants(Operation op)
  {
    Set<StateObserver> blockingSO = SetFactory.createSet(StateObserver.class);
    for (StateObserver currSO : main.stateObservers().stateObserverSet()) {
      if (currSO.invariant().contains(op)) {
        blockingSO.add(currSO);
      }
    }
    return processOccurencesInInvariants(blockingSO);
  }
 
  private String occurencesInCondsReacts(Operation op)
  {
    Set<Event> blockingEvents = SetFactory.createSet(Event.class);
    for (Event ev : main.events().eventSet()) {
      for (CondReact cr : ev.conditionsReactions()) {
        if (cr.cond().contains(op)) {
          blockingEvents.add(ev);
          break;
        }
        if (cr.react().contains(op)) {
          blockingEvents.add(ev);
          break;
        }
      }
    }
    return processOccurrencesInCondsReacts(blockingEvents);
  }*/
 
  /*
   *
   * State observer checkers
   *
   */
 
  public boolean canAdd(StateObserverInfo newSoInfo)
  {
    Name newSoName = newSoInfo.name();
    if (soExists(newSoName)) {
      main.soError(Constants.EXISTING_STATE_OBSERVER);
      return false;
    }
    if (eventExists(newSoName)) {
      main.soError(Constants.EXISTING_EVENT);
      return false;
    }
    return true;
  }
 
  public boolean canDelete(StateObserver so)
  {
    // return !soIsUsed(so);
    if (main.stateTable().usedSO() != null) {
      for (StateObserver currSO : main.stateTable().usedSO()) {
        if (so.equals(currSO)) {
          main.soError(Constants.USED_STATE_OBSERVER);
          return false;
        }
      }
    }
    return true;
  }
 
  public boolean canUpdate(StateObserver oldSo, StateObserverInfo newSoInfo)
  {
    Name newSoName = newSoInfo.name();
    if (oldSo.name().equals(newSoName)) {
      return true;
    }
    if (soExists(newSoName)) {
      main.soError(Constants.EXISTING_STATE_OBSERVER);
      return false;
    }
    if (eventExists(newSoName)) {
      main.soError(Constants.EXISTING_EVENT);
      return false;
    }
    return true;
  }
 
  private boolean soExists(Name soName)
  {
    for (StateObserver so : main.stateObservers().soList()) {
      if (so.name().equals(soName))
        return true;
    }
    return false;
  }
 
  /**
   * A state observer may be used in:
   * - Invariants
   * - Conditions and reactions
  
  private boolean soIsUsed(StateObserver so)
  {
    String invOccur = occurencesInInvariants(so);
    String crOccur = occurencesInCondsReacts(so);
    String errorString = invOccur + crOccur;
    if (!errorString.isEmpty()) {
      main.soError("* State observers:\n" + errorString);
      return true;
    }
    return false;
  }
 
  private String occurencesInInvariants(StateObserver so)
  {
    Set<StateObserver> blockingSO = SetFactory.createSet(StateObserver.class);
    for (StateObserver currSO : main.stateObservers().stateObserverSet()) {
      if (currSO.invariant().contains(so)) {
        blockingSO.add(currSO);
      }
    }
    return processOccurencesInInvariants(blockingSO);
  }
 
  private String occurencesInCondsReacts(StateObserver so)
  {
    Set<Event> blockingEvents = SetFactory.createSet(Event.class);
    for (Event ev : main.events().eventSet()) {
      for (CondReact cr : ev.conditionsReactions()) {
        if (cr.cond().contains(so)) {
          blockingEvents.add(ev);
          break;
        }
        if (cr.react().contains(so)) {
          blockingEvents.add(ev);
          break;
        }
      }
    }
    return processOccurrencesInCondsReacts(blockingEvents);
  }*/
 
  /*
   *
   * Event checkers
   *
   */
 
  public boolean canAdd(EventInfo newEventInfo)
  {
    Name newEventName = newEventInfo.name();
    if (eventExists(newEventName)) {
      main.eventsError(Constants.EXISTING_EVENT);
      return false;
    }
    if (soExists(newEventName)) {
      main.eventsError(Constants.EXISTING_STATE_OBSERVER);
      return false;
    }
    if (paramsAreRepeated(newEventInfo.paramsInfo())) {
      main.eventsError(Constants.REPEATED_PARAMETERS);
      return false;
    }
    return true;
  }
 
  public boolean canDelete(Event event)
  {
    // return !eventIsUsed(event);
    return true;
  }
 
  public boolean canUpdate(Event oldEvent, EventInfo newEventInfo)
  {
    Name newEventName = newEventInfo.name();
    if (!oldEvent.name().equals(newEventName)) {
      if (eventExists(newEventName)) {
        main.eventsError(Constants.EXISTING_EVENT);
        return false;
      }
      if (soExists(newEventName)) {
        main.eventsError(Constants.EXISTING_STATE_OBSERVER);
        return false;
      }
    }
    if (paramsAreRepeated(newEventInfo.paramsInfo())) {
      main.eventsError(Constants.REPEATED_PARAMETERS);
      return false;
    }
    return true;
  }
 
  private boolean eventExists(Name eventName)
  {
    for (Event ev : main.events().eventList()) {
      if (ev.name().equals(eventName))
        return true;
    }
    return false;
  }
 
  /**
   * An event may be used in:
   * - Invariants
   * - Conditions and reactions
  
  private boolean eventIsUsed(Event event)
  {
    String invOccur = occurencesInInvariants(event);
    String crOccur = occurencesInCondsReacts(event);
    String errorString = invOccur + crOccur;
    if (!errorString.isEmpty()) {
      main.eventsError("* Events:\n" + errorString);
      return true;
    }
    return false;
  }
 
  private String occurencesInInvariants(Event event)
  {
    Set<StateObserver> blockingSO = SetFactory.createSet(StateObserver.class);
    for (StateObserver currSO : main.stateObservers().stateObserverSet()) {
      if (currSO.invariant().contains(event)) {
        blockingSO.add(currSO);
      }
    }
    return processOccurencesInInvariants(blockingSO);
  }
 
  private String occurencesInCondsReacts(Event event)
  {
    Set<Event> blockingEvents = SetFactory.createSet(Event.class);
    for (Event ev : main.events().eventSet()) {
      for (CondReact cr : ev.conditionsReactions()) {
        if (cr.cond().contains(event)) {
          blockingEvents.add(ev);
          break;
        }
        if (cr.react().contains(event)) {
          blockingEvents.add(ev);
          break;
        }
      }
    }
    return processOccurrencesInCondsReacts(blockingEvents);
  }*/
 
  /*
   *
   * Condition reaction checkers
   *
   */
 
  public boolean canAdd(Event event, CondReactInfo newCrInfo)
  {
    if (crExists(event, newCrInfo)) {
      main.eventsError(Constants.EXISTING_COND_REACT);
      return false;
    }
    return true;
  }
 
  public boolean canDelete(CondReact cr)
  {
    return true;
  }
 
  public boolean canUpdate(CondReact cr,
                           CondReactInfo newCrInfo)
  {
    Event event = null;
    for (Event currEvent : main.events().eventList()) {
      if (currEvent.condsReacts().contains(cr)) {
        event = currEvent;
        break;
      }
    }
    if (!cr.cond().equals(newCrInfo.cond()) && crExists(event, newCrInfo)) {
      main.eventsError(Constants.EXISTING_COND_REACT);
      return false;
    }
    return true;
  }
 
  private boolean crExists(Event event, CondReactInfo crInfo)
  {
    Expr cond = crInfo.cond();
    for (CondReact cr : event.condsReacts()) {
      if (cr.cond().equals(cond)) {
        return true;
      }
    }
    return false;
  }
 
  /*
   *
   * State checkers
   *
   */
 
  public boolean canDefine(Name newStateName)
  {
    for (Row row : main.stateTable().rows()) {
      if (row.name().equals(newStateName)) {
        main.stError(Constants.EXISTING_STATE);
        return false;
      }
    }
    return true;
  }
 
  /*
   *
   * Private methods
   *
   */
 
  /*private String processOccurencesInInvariants(Set<StateObserver> blockingSO)
  {
    StringBuilder builder = new StringBuilder();
    if (!blockingSO.isEmpty()) {
      for (StateObserver currSO : blockingSO) {
        builder.append(currSO + "\n");
      }
    }
    return builder.toString();
  }
 
  private String processOccurrencesInCondsReacts(Set<Event> blockingEvents)
  {
    StringBuilder builder = new StringBuilder();
    if (!blockingEvents.isEmpty()) {
      for (Event ev : blockingEvents) {
        builder.append(ev + "\n");
      }
    }
    return builder.toString();
  }*/
 
  private boolean paramsAreRepeated(Set<ParameterInfo> paramsInfo)
  {
    if (paramsInfo == null) {
      return false;
    }
    Set<Name> paramsNames = SetFactory.createSet(Name.class);
    // We add the name of each parameter to the set;
    // since it is a set, it will not add a name if
    // it is already in the set.
    for (ParameterInfo pi : paramsInfo) {
      if (!paramsNames.add(pi.name())) {
        return true;
      }
    }
    return false;
  }
 
  private boolean typeExists(Name typeName)
  {
    if (classExists(typeName)) {
      main.inputCDError(Constants.EXISTING_CLASS);
      return true;
    }
    if (enumExists(typeName)) {
      main.inputCDError(Constants.EXISTING_ENUM);
      return true;
    }
    if (predefinedTypesNames.contains(typeName)) {
      main.inputCDError(Constants.EXISTING_TYPE);
      return true;
    }
    return false;
  }
 
  /**
   * A type may be used by:
   * - Attributes
   * - Operations and their parameters
   * - State observers
   * - Events parameters
   */
  private boolean typeIsUsed(Name typeName)
  {
    // Classes
    Set<Attribute> blockingAttributes = SetFactory.createSet(Attribute.class);
    Set<Operation> blockingOperations = SetFactory.createSet(Operation.class);
    for (Class currCl : main.inputCD().classes()) {
      // We ignore the attributes and operations
      // of the class we are going to delete.
      if (currCl.name().equals(typeName)) {
        continue;
      }   
      // Attributes
      for (Attribute attr : currCl.attributes()) {
        // Attribute type
        if (attr.type().name().equals(typeName)) {
          blockingAttributes.add(attr);
        }
      } 
      // Operations
      for (Operation op : currCl.operations()) {
        // Operation return type
        if (op.returnType().name().equals(typeName)) {
          blockingOperations.add(op);
        }
        // Parameters types
        for (Parameter param : op.parameters()) {
          if (param.type().name().equals(typeName)) {
            blockingOperations.add(op);
            break;
          }
        }
      }
    }
    // State observers
    Set<StateObserver> blockingSO = SetFactory.createSet(StateObserver.class);
    for (StateObserver so : main.stateObservers().soList()) {
      if (so.type().name().equals(typeName)) {
        blockingSO.add(so);
      }
    }
    // Events
    Set<Event> blockingEvents = SetFactory.createSet(Event.class);
    for (Event ev : main.events().eventList()) {
      // Parameters types
      for (Parameter param : ev.parameters()) {
        if (param.type().name().equals(typeName)) {
          blockingEvents.add(ev);
          break;
        }
      }
    }
    // Error string builder
    StringBuilder builder = new StringBuilder();
    // Process blocking attributes
    if (!blockingAttributes.isEmpty()) {
      builder.append("* Attributes:\n");
      for (Attribute attr : blockingAttributes) {
        builder.append(attr + " (class " + ((Class) attr.containedIn()).name() + ")\n");
      }
    }
    // Process blocking operations
    if (!blockingOperations.isEmpty()) {
      builder.append("* Operations:\n");
      for (Operation op : blockingOperations) {
        builder.append(op + " (class " + ((Class) op.containedIn()).name() + ")\n");
      }
    }
    // Process blocking state observers
    if (!blockingSO.isEmpty()) {
      builder.append("* State observers:\n");
      for (StateObserver so : blockingSO) {
        builder.append(so + "\n");
      }
    }
    // Process blocking events
    if (!blockingEvents.isEmpty()) {
      builder.append("* Events:\n");
      for (Event ev : blockingEvents) {
        builder.append(ev + "\n");
      }
    }
    // Error string
    String errorString =  builder.toString();
    if (!errorString.isEmpty()) {
      String intro = "Cannot delete given class/enum, corresponding type is used in following elements:\n";
      main.inputCDError(intro + errorString);
      return true;
    }
    return false;
  }
}
TOP

Related Classes of easysm.executors.Checker

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.