CommonUtilExtension.java

/**
 * Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
 * All Rights Reserved.
 * 
 * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
 * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
 * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 * 
 * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
 * 
 * This program includes and/or can make use of certain third party source code, object code, documentation and other
 * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
 * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
 * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
 * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
 * aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
 * censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
 */
package org.osate.alisa.common.util;

import com.google.common.base.Objects;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xsemantics.runtime.Result;
import org.eclipse.xsemantics.runtime.RuleEnvironment;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.osate.aadl2.Classifier;
import org.osate.aadl2.ComponentClassifier;
import org.osate.aadl2.ComponentImplementation;
import org.osate.aadl2.ComponentType;
import org.osate.aadl2.Connection;
import org.osate.aadl2.EndToEndFlow;
import org.osate.aadl2.Feature;
import org.osate.aadl2.FlowSpecification;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.PropertyExpression;
import org.osate.aadl2.PropertyValue;
import org.osate.aadl2.Subcomponent;
import org.osate.aadl2.instance.ComponentInstance;
import org.osate.aadl2.instance.ConnectionInstance;
import org.osate.aadl2.instance.ConnectionReference;
import org.osate.aadl2.instance.EndToEndFlowInstance;
import org.osate.aadl2.instance.InstanceObject;
import org.osate.aadl2.util.Aadl2Util;
import org.osate.alisa.common.common.AModelReference;
import org.osate.alisa.common.common.AUnitExpression;
import org.osate.alisa.common.common.AVariableDeclaration;
import org.osate.alisa.common.common.AVariableReference;
import org.osate.alisa.common.common.ComputeDeclaration;
import org.osate.alisa.common.common.Description;
import org.osate.alisa.common.common.DescriptionElement;
import org.osate.alisa.common.common.ValDeclaration;
import org.osate.alisa.common.typing.CommonInterpreter;

@SuppressWarnings("all")
public class CommonUtilExtension {
  private static CommonInterpreter interpreter = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(
    URI.createFileURI("dummy.___common___")).<CommonInterpreter>get(CommonInterpreter.class);

  public static String toText(final Description desc, final NamedElement target) {
    final Function1<DescriptionElement, String> _function = (DescriptionElement it) -> {
      return CommonUtilExtension.toText(it, target);
    };
    return IterableExtensions.join(ListExtensions.<DescriptionElement, String>map(desc.getDescription(), _function));
  }

  private static String stripNewlineTab(final String s) {
    boolean _contains = s.contains("\n");
    if (_contains) {
      return s.replaceAll("\n", " ").replaceAll("\r", "").replaceAll("\t", "");
    }
    boolean _contains_1 = s.contains("\r");
    if (_contains_1) {
      return s.replaceAll("\r", " ").replaceAll("\t", "");
    }
    return s.replace("\t", " ").replaceAll("\t", "");
  }

  public static String toText(final DescriptionElement de, final NamedElement target) {
    String _xifexpression = null;
    String _text = de.getText();
    boolean _tripleNotEquals = (_text != null);
    if (_tripleNotEquals) {
      _xifexpression = CommonUtilExtension.stripNewlineTab(de.getText());
    } else {
      String _xifexpression_1 = null;
      if ((de.isThisTarget() && (target != null))) {
        _xifexpression_1 = target.getQualifiedName();
      } else {
        String _xifexpression_2 = null;
        AUnitExpression _showValue = de.getShowValue();
        boolean _tripleNotEquals_1 = (_showValue != null);
        if (_tripleNotEquals_1) {
          String _xblockexpression = null;
          {
            final AUnitExpression decl = de.getShowValue();
            String _xifexpression_3 = null;
            boolean _eIsProxy = decl.eIsProxy();
            if (_eIsProxy) {
              _xifexpression_3 = "TBD";
            } else {
              String _xblockexpression_1 = null;
              {
                PropertyExpression _expression = decl.getExpression();
                final AVariableDeclaration variable = ((AVariableReference) _expression).getVariable();
                String _switchResult = null;
                boolean _matched = false;
                if (variable instanceof ComputeDeclaration) {
                  _matched=true;
                  _switchResult = ((ComputeDeclaration)variable).getName();
                }
                if (!_matched) {
                  if (variable instanceof ValDeclaration) {
                    _matched=true;
                    String _xblockexpression_2 = null;
                    {
                      final PropertyExpression expr = ((ValDeclaration)variable).getValue();
                      if ((expr instanceof AModelReference)) {
                        return CommonUtilExtension.toText(((AModelReference)expr));
                      }
                      String _xifexpression_4 = null;
                      if ((target instanceof InstanceObject)) {
                        String _xblockexpression_3 = null;
                        {
                          final RuleEnvironment env = new RuleEnvironment();
                          HashMap<String, PropertyExpression> _hashMap = new HashMap<String, PropertyExpression>();
                          env.add("vals", _hashMap);
                          HashMap<String, Object> _hashMap_1 = new HashMap<String, Object>();
                          env.add("computes", _hashMap_1);
                          env.add("target", target);
                          final Result<PropertyValue> result = CommonUtilExtension.interpreter.interpretExpression(env, decl);
                          boolean _failed = result.failed();
                          if (_failed) {
                            String _name = ((ValDeclaration)variable).getName();
                            String _plus = ("Could not evaluate expression for " + _name);
                            String _plus_1 = (_plus + ": ");
                            String _failedMsg = CommonUtilExtension.getFailedMsg(result.getRuleFailedException());
                            return (_plus_1 + _failedMsg);
                          }
                          PropertyValue x = result.getValue();
                          String _xifexpression_5 = null;
                          if ((x == null)) {
                            _xifexpression_5 = "TBD";
                          } else {
                            _xifexpression_5 = x.toString();
                          }
                          _xblockexpression_3 = _xifexpression_5;
                        }
                        _xifexpression_4 = _xblockexpression_3;
                      } else {
                        String _name = ((ValDeclaration)variable).getName();
                        String _plus = ("value of \'" + _name);
                        _xifexpression_4 = (_plus + "\'");
                      }
                      _xblockexpression_2 = _xifexpression_4;
                    }
                    _switchResult = _xblockexpression_2;
                  }
                }
                _xblockexpression_1 = _switchResult;
              }
              _xifexpression_3 = _xblockexpression_1;
            }
            _xblockexpression = _xifexpression_3;
          }
          _xifexpression_2 = _xblockexpression;
        } else {
          _xifexpression_2 = "";
        }
        _xifexpression_1 = _xifexpression_2;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }

  public static String getFailedMsg(final Throwable e) {
    Throwable tmp = e;
    while (((tmp.getCause() != null) && (!Objects.equal(tmp.getCause(), tmp)))) {
      tmp = tmp.getCause();
    }
    return tmp.getMessage();
  }

  public static String toText(final AModelReference aref) {
    AModelReference _prev = aref.getPrev();
    boolean _tripleEquals = (_prev == null);
    if (_tripleEquals) {
      return "this";
    } else {
      String _text = CommonUtilExtension.toText(aref.getPrev());
      String _plus = (_text + ".");
      NamedElement _modelElement = aref.getModelElement();
      String _name = null;
      if (_modelElement!=null) {
        _name=_modelElement.getName();
      }
      return (_plus + _name);
    }
  }

  public static boolean isSameorExtends(final Classifier target, final Classifier ancestor) {
    if ((Aadl2Util.isNull(target) || Aadl2Util.isNull(ancestor))) {
      return false;
    }
    Classifier ext = target;
    if (((target instanceof ComponentImplementation) && (ancestor instanceof ComponentType))) {
      ext = ((ComponentImplementation) target).getType();
    }
    while ((!Aadl2Util.isNull(ext))) {
      {
        boolean _equalsIgnoreCase = ancestor.getName().equalsIgnoreCase(ext.getName());
        if (_equalsIgnoreCase) {
          return true;
        }
        ext = ext.getExtended();
      }
    }
    return false;
  }

  public static boolean isSameorExtendsURI(final ComponentClassifier target, final URI ancestorURI) {
    if (((target == null) || (ancestorURI == null))) {
      return false;
    }
    Classifier ext = target;
    while ((ext != null)) {
      {
        URI _uRI = EcoreUtil.getURI(ext);
        boolean _equals = Objects.equal(ancestorURI, _uRI);
        if (_equals) {
          return true;
        }
        ext = ext.getExtended();
      }
    }
    if ((target instanceof ComponentImplementation)) {
      ext = ((ComponentImplementation)target).getType();
      while ((ext != null)) {
        {
          URI _uRI = EcoreUtil.getURI(ext);
          boolean _equals = Objects.equal(ancestorURI, _uRI);
          if (_equals) {
            return true;
          }
          ext = ext.getExtended();
        }
      }
    }
    return false;
  }

  public static InstanceObject findElementInstance(final ComponentInstance io, final NamedElement element) {
    final String n = element.getName();
    boolean _matched = false;
    if (element instanceof EndToEndFlow) {
      _matched=true;
      return CommonUtilExtension.findETEFInstance(io.getEndToEndFlows(), n);
    }
    if (!_matched) {
      if (element instanceof Subcomponent) {
        _matched=true;
        return CommonUtilExtension.findElementInstanceInList(io.getComponentInstances(), n);
      }
    }
    if (!_matched) {
      if (element instanceof Feature) {
        _matched=true;
        return CommonUtilExtension.findElementInstanceInList(io.getFeatureInstances(), n);
      }
    }
    if (!_matched) {
      if (element instanceof FlowSpecification) {
        _matched=true;
        return CommonUtilExtension.findElementInstanceInList(io.getFlowSpecifications(), n);
      }
    }
    if (!_matched) {
      if (element instanceof Connection) {
        _matched=true;
        final ConnectionInstance conn = CommonUtilExtension.findConnectionInstance(io.getConnectionInstances(), n);
        return conn;
      }
    }
    return null;
  }

  public static InstanceObject findElementInstanceInList(final List<? extends InstanceObject> instancelist, final String name) {
    for (final InstanceObject ei : instancelist) {
      {
        final String n1 = ei.getName();
        boolean _equalsIgnoreCase = n1.equalsIgnoreCase(name);
        if (_equalsIgnoreCase) {
          return ei;
        }
      }
    }
    return null;
  }

  public static ConnectionInstance findConnectionInstance(final Collection<ConnectionInstance> connilist, final String name) {
    for (final ConnectionInstance ei : connilist) {
      {
        final Connection conn = CommonUtilExtension.getCrossConnection(ei);
        if (((conn != null) && name.equalsIgnoreCase(conn.getName()))) {
          return ei;
        }
      }
    }
    return null;
  }

  /**
   * @since 2.0
   */
  public static EndToEndFlowInstance findETEFInstance(final Collection<EndToEndFlowInstance> etefilist, final String name) {
    for (final EndToEndFlowInstance ei : etefilist) {
      {
        final EndToEndFlow etef = ei.getEndToEndFlow();
        if (((etef != null) && name.equalsIgnoreCase(etef.getName()))) {
          return ei;
        }
      }
    }
    return null;
  }

  public static Collection<ConnectionInstance> findConnectionInstances(final Collection<ConnectionInstance> connilist, final ConnectionInstance conni) {
    final Collection<ConnectionInstance> result = CollectionLiterals.<ConnectionInstance>newArrayList();
    final Connection targetconn = CommonUtilExtension.getCrossConnection(conni);
    for (final ConnectionInstance ei : connilist) {
      {
        final Connection conn = CommonUtilExtension.getCrossConnection(ei);
        boolean _equals = Objects.equal(targetconn, conn);
        if (_equals) {
          result.add(ei);
        }
      }
    }
    return result;
  }

  public static Connection getCrossConnection(final ConnectionInstance conni) {
    EList<ConnectionReference> _connectionReferences = conni.getConnectionReferences();
    for (final ConnectionReference connref : _connectionReferences) {
      {
        final Connection conn = connref.getConnection();
        boolean _isAcross = conn.isAcross();
        if (_isAcross) {
          return conn;
        }
      }
    }
    return null;
  }

  public static Iterable<Connection> getCrossConnections(final ComponentImplementation ci) {
    final Function1<Connection, Boolean> _function = (Connection conn) -> {
      return Boolean.valueOf(conn.isAcross());
    };
    return IterableExtensions.<Connection>filter(ci.getAllConnections(), _function);
  }

  public static final CommonUtilExtension eInstance = new CommonUtilExtension();

  /**
   * @since 2.0
   */
  public static Collection<EndToEndFlowInstance> findETEFInstances(final Collection<EndToEndFlowInstance> etefilist, final EndToEndFlowInstance etefi) {
    final Collection<EndToEndFlowInstance> result = CollectionLiterals.<EndToEndFlowInstance>newArrayList();
    final EndToEndFlow tetef = etefi.getEndToEndFlow();
    for (final EndToEndFlowInstance ei : etefilist) {
      EndToEndFlow _endToEndFlow = ei.getEndToEndFlow();
      boolean _equals = Objects.equal(tetef, _endToEndFlow);
      if (_equals) {
        result.add(ei);
      }
    }
    return result;
  }
}