blob: 5ca88d4628c91982c66e2cd6682a2b57febbea25 [file] [log] [blame]
/**
* Copyright (c) 2011 protos software gmbh (http://www.protos.de).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* CONTRIBUTORS:
* Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
*/
package org.eclipse.etrice.generator.generic;
import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import javax.inject.Inject;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.etrice.core.genmodel.etricegen.AbstractInstance;
import org.eclipse.etrice.core.genmodel.etricegen.InterfaceItemInstance;
import org.eclipse.etrice.core.genmodel.etricegen.PortInstance;
import org.eclipse.etrice.core.genmodel.etricegen.SAPInstance;
import org.eclipse.etrice.core.genmodel.etricegen.ServiceImplInstance;
import org.eclipse.etrice.core.genmodel.etricegen.StructureInstance;
import org.eclipse.etrice.core.room.ActorClass;
import org.eclipse.etrice.core.room.ExternalPort;
import org.eclipse.etrice.core.room.GeneralProtocolClass;
import org.eclipse.etrice.core.room.Message;
import org.eclipse.etrice.core.room.MessageHandler;
import org.eclipse.etrice.core.room.Port;
import org.eclipse.etrice.core.room.PortClass;
import org.eclipse.etrice.core.room.ProtocolClass;
import org.eclipse.etrice.core.room.RefableType;
import org.eclipse.etrice.core.room.RoomClass;
import org.eclipse.etrice.core.room.RoomModel;
import org.eclipse.etrice.core.room.SAP;
import org.eclipse.etrice.core.room.SPP;
import org.eclipse.etrice.core.room.ServiceImplementation;
import org.eclipse.etrice.core.room.StandardOperation;
import org.eclipse.etrice.core.room.VarDecl;
import org.eclipse.etrice.core.room.util.RoomHelpers;
import org.eclipse.etrice.generator.fsm.base.FileSystemHelpers;
import org.eclipse.etrice.generator.fsm.generic.FSMExtensions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
/**
* collection of convenience functions for code generation
*/
@Singleton
@SuppressWarnings("all")
public class RoomExtensions extends FSMExtensions {
public final String NEWLINE = System.getProperty("line.separator");
private static String genDir = "/src-gen/";
private static String genInfoDir = "/src-gen-info/";
private static String genDocDir = "/doc-gen/";
@Inject
@Extension
protected RoomHelpers _roomHelpers;
public static String setDefaultGenDir() {
return RoomExtensions.genDir = "/src-gen/";
}
public static String setDefaultGenInfoDir() {
return RoomExtensions.genInfoDir = "/src-gen-info/";
}
public static String setDefaultGenDocDir() {
return RoomExtensions.genDocDir = "/doc-gen/";
}
public static String setGenDir(final String dir) {
return RoomExtensions.genDir = (("/" + dir) + "/");
}
public static String setGenInfoDir(final String dir) {
return RoomExtensions.genInfoDir = (("/" + dir) + "/");
}
public static String setGenDocDir(final String dir) {
return RoomExtensions.genDocDir = (("/" + dir) + "/");
}
/**
* a specialized version of {@link #union(Iterable, Iterable)}
* @param in1 an iterable of type T
* @param in2 a second iterable of type T
* @return the union of the two iterables as new list
*/
public List<Port> punion(final Iterable<Port> in1, final Iterable<ExternalPort> in2) {
final ArrayList<Port> ret = new ArrayList<Port>();
final Consumer<ExternalPort> _function = new Consumer<ExternalPort>() {
public void accept(final ExternalPort e) {
Port _interfacePort = e.getInterfacePort();
ret.add(_interfacePort);
}
};
in2.forEach(_function);
Iterables.<Port>addAll(ret, in1);
return ret;
}
/**
* @return the relative path to the destination folder for the generated code
*/
public String getGenerationPathSegment() {
return RoomExtensions.genDir;
}
/**
* @return the relative path to the destination folder for the generated code
*/
public String getGenerationInfoSegment() {
return RoomExtensions.genInfoDir;
}
/**
* @return the relative path to the destination folder for the generated documentation
*/
public String getDocGenerationPathSegment() {
return RoomExtensions.genDocDir;
}
/**
* @param e an {@link EObject}
* @return the URI of the EObject's resource as file string
* (or an empty string if no such resource exists)
*/
public String getModelPath(final EObject e) {
Resource res = e.eResource();
boolean _equals = Objects.equal(res, null);
if (_equals) {
return "";
} else {
URI _uRI = res.getURI();
return _uRI.toFileString();
}
}
/**
* @param rc a {@link RoomClass}
* @return the name of the room model which also serves as a package name
*/
public String getPackage(final RoomClass rc) {
EObject _eContainer = rc.eContainer();
return ((RoomModel) _eContainer).getName();
}
/**
* @param rc a {@link RoomClass}
* @return the name of the room model followed by the class name and all . replaced with _
*/
public String getFullyQualifiedName(final RoomClass rc) {
String _package = this.getPackage(rc);
String _replace = _package.replace(".", "_");
String _plus = (_replace + "_");
String _name = rc.getName();
return (_plus + _name);
}
/**
* @param packageName a dot (.) separated package anem
* @return the input with dots replaced with slashes (/)
*/
public String getPathFromPackage(final String packageName) {
String _replaceAll = packageName.replaceAll("\\.", "/");
return (_replaceAll + "/");
}
/**
* @param rc a {@link RoomClass}
* @return the relative folder path of the package
* (as defined by the Java convention)
*/
public String getPath(final RoomClass rc) {
String _package = this.getPackage(rc);
return this.getPathFromPackage(_package);
}
/**
* @param e an {@link EObject}
* @return the path of the Eclipse project containing the EObject's resource
*/
public String getProjectPath(final EObject e) {
final URI res = FileSystemHelpers.getProjectURI(e);
boolean _equals = Objects.equal(res, null);
if (_equals) {
return "";
}
return res.toFileString();
}
/**
* @param e an {@link EObject}
* @return the concatenation of the object's project path
* with the {@link #getGenerationPathSegment()}
*/
public String getGenerationTargetPath(final EObject e) {
String _projectPath = this.getProjectPath(e);
String _generationPathSegment = this.getGenerationPathSegment();
return (_projectPath + _generationPathSegment);
}
/**
* @param e an {@link EObject}
* @return the concatenation of the object's project path
* with the {@link #getGenerationInfoSegment()}
*/
public String getGenerationInfoPath(final EObject e) {
String _projectPath = this.getProjectPath(e);
String _generationInfoSegment = this.getGenerationInfoSegment();
return (_projectPath + _generationInfoSegment);
}
/**
* @param e an {@link EObject}
* @return the concatenation of the objects project path
* with the {@link #getDocGenerationPathSegment()}
*/
public String getDocGenerationTargetPath(final EObject e) {
String _projectPath = this.getProjectPath(e);
String _docGenerationPathSegment = this.getDocGenerationPathSegment();
return (_projectPath + _docGenerationPathSegment);
}
/**
* makes a valid identifier from a path string
* @param path a slash (/) separated path
* @return the path with slashes (and colons as in replicated actors) replaced by underscores (_)
*/
public String getPathName(final String path) {
String _replaceAll = path.replaceAll("/", "_");
return _replaceAll.replaceAll(":", "_");
}
/**
* @param p a {@link Port}
* @return a name for the associated port class
*/
protected String _getPortClassName(final Port p) {
String _xifexpression = null;
GeneralProtocolClass _protocol = p.getProtocol();
if ((_protocol instanceof ProtocolClass)) {
GeneralProtocolClass _protocol_1 = p.getProtocol();
boolean _isConjugated = p.isConjugated();
boolean _isReplicated = p.isReplicated();
_xifexpression = this.getPortClassName(((ProtocolClass) _protocol_1), _isConjugated, _isReplicated);
} else {
_xifexpression = "";
}
return _xifexpression;
}
/**
* @param p a {@link ExternalPort}
* @return a name for the associated port class
*/
protected String _getPortClassName(final ExternalPort p) {
Port _interfacePort = p.getInterfacePort();
return this.getPortClassName(_interfacePort);
}
/**
* @param sap a {@link SAP}
* @return a name for the associated port class
*/
protected String _getPortClassName(final SAP sap) {
ProtocolClass _protocol = sap.getProtocol();
return this.getPortClassName(_protocol, true);
}
/**
* @param spp a {@link SPP}
* @return a name for the associated port class
*/
protected String _getPortClassName(final SPP spp) {
ProtocolClass _protocol = spp.getProtocol();
return this.getPortClassName(_protocol, false, true);
}
/**
* @param svc a {@link ServiceImplementation}
* @return a name for the associated port class
*/
protected String _getPortClassName(final ServiceImplementation svc) {
SPP _spp = svc.getSpp();
ProtocolClass _protocol = _spp.getProtocol();
return this.getPortClassName(_protocol, false, true);
}
/**
* @param p a {@link ProtocolClass}
* @param conj if <code>true</code> consider conjugate port, else regular
* @return a name for the associated port class
*/
public String getPortClassName(final ProtocolClass p, final boolean conj) {
return this.getPortClassName(p, conj, false);
}
/**
* @param p a {@link ProtocolClass}
* @param conj if <code>true</code> consider conjugate port, else regular
* @param repl if <code>true</code> class name for replicated port
* else for plain port
* @return a name for the associated port class
*/
public String getPortClassName(final ProtocolClass p, final boolean conj, final boolean repl) {
String _name = p.getName();
String _xifexpression = null;
if (conj) {
_xifexpression = "Conj";
} else {
_xifexpression = "";
}
String _plus = (_name + _xifexpression);
String _xifexpression_1 = null;
if (repl) {
_xifexpression_1 = "Repl";
} else {
_xifexpression_1 = "";
}
String _plus_1 = (_plus + _xifexpression_1);
return (_plus_1 + "Port");
}
/**
* @param pc a {@link ProtocolClass}
* @param conj flag indicating the desired {@link PortClass}
* @return the port class
*/
public PortClass getPortClass(final ProtocolClass pc, final boolean conj) {
if (conj) {
return pc.getConjugated();
} else {
return pc.getRegular();
}
}
/**
* @param pc a {@link ProtocolClass}
* @param conj flag indicating the desired communication direction
* @return <code>true</code> if a send handler is specified for this direction
*/
public boolean handlesSend(final ProtocolClass pc, final boolean conj) {
PortClass _portClass = this.getPortClass(pc, conj);
boolean _equals = Objects.equal(_portClass, null);
if (_equals) {
return false;
} else {
PortClass _portClass_1 = this.getPortClass(pc, conj);
EList<MessageHandler> _msgHandlers = _portClass_1.getMsgHandlers();
for (final MessageHandler hdlr : _msgHandlers) {
List<Message> _allMessages = this._roomHelpers.getAllMessages(pc, conj);
Message _msg = hdlr.getMsg();
boolean _contains = _allMessages.contains(_msg);
if (_contains) {
return true;
}
}
}
return false;
}
/**
* @param pc a {@link ProtocolClass}
* @param conj flag indicating the desired communication direction
* @return <code>true</code> if a receive handler is specified for this direction
*/
public boolean handlesReceive(final ProtocolClass pc, final boolean conj) {
PortClass _portClass = this.getPortClass(pc, conj);
boolean _equals = Objects.equal(_portClass, null);
if (_equals) {
return false;
} else {
PortClass _portClass_1 = this.getPortClass(pc, conj);
EList<MessageHandler> _msgHandlers = _portClass_1.getMsgHandlers();
for (final MessageHandler hdlr : _msgHandlers) {
List<Message> _allMessages = this._roomHelpers.getAllMessages(pc, (!conj));
Message _msg = hdlr.getMsg();
boolean _contains = _allMessages.contains(_msg);
if (_contains) {
return true;
}
}
}
return false;
}
/**
* @param iii an {@link InterfaceItemInstance}
* @return <code>true</code> if the interface item instance is logically conjugate
*/
public boolean isConjugated(final InterfaceItemInstance iii) {
if ((iii instanceof PortInstance)) {
Port _port = ((PortInstance) iii).getPort();
return _port.isConjugated();
} else {
if ((iii instanceof SAPInstance)) {
return true;
} else {
if ((iii instanceof ServiceImplInstance)) {
return false;
} else {
return false;
}
}
}
}
/**
* @param pc a {@link ProtocolClass}
* @param conj flag indicating the desired communication direction
* @return a list of defined receive {@link MessageHandler} for this direction
*/
public List<MessageHandler> getReceiveHandlers(final ProtocolClass pc, final boolean conj) {
PortClass _portClass = this.getPortClass(pc, conj);
boolean _equals = Objects.equal(_portClass, null);
if (_equals) {
return new ArrayList<MessageHandler>();
} else {
ArrayList<MessageHandler> res = new ArrayList<MessageHandler>();
PortClass _portClass_1 = this.getPortClass(pc, conj);
EList<MessageHandler> _msgHandlers = _portClass_1.getMsgHandlers();
for (final MessageHandler hdlr : _msgHandlers) {
List<Message> _allMessages = this._roomHelpers.getAllMessages(pc, (!conj));
Message _msg = hdlr.getMsg();
boolean _contains = _allMessages.contains(_msg);
if (_contains) {
res.add(hdlr);
}
}
return res;
}
}
/**
* @param pc a {@link ProtocolClass}
* @param conj flag indicating the desired communication direction
* @return a list of defined send {@link MessageHandler} for this direction
*/
public List<MessageHandler> getSendHandlers(final ProtocolClass pc, final boolean conj) {
PortClass _portClass = this.getPortClass(pc, conj);
boolean _equals = Objects.equal(_portClass, null);
if (_equals) {
return new ArrayList<MessageHandler>();
} else {
ArrayList<MessageHandler> res = new ArrayList<MessageHandler>();
PortClass _portClass_1 = this.getPortClass(pc, conj);
EList<MessageHandler> _msgHandlers = _portClass_1.getMsgHandlers();
for (final MessageHandler hdlr : _msgHandlers) {
List<Message> _allMessages = this._roomHelpers.getAllMessages(pc, conj);
Message _msg = hdlr.getMsg();
boolean _contains = _allMessages.contains(_msg);
if (_contains) {
res.add(hdlr);
}
}
return res;
}
}
/**
* @param m a {@link Message}
* @param conj flag indicating the desired communication direction
* @return a send {@link MessageHandler} for this direction if it is defined, <code>null</code> else
*/
public MessageHandler getSendHandler(final Message m, final boolean conj) {
EObject _eContainer = m.eContainer();
List<MessageHandler> _sendHandlers = this.getSendHandlers(((ProtocolClass) _eContainer), conj);
final Function1<MessageHandler, Boolean> _function = new Function1<MessageHandler, Boolean>() {
public Boolean apply(final MessageHandler e) {
Message _msg = e.getMsg();
return Boolean.valueOf(Objects.equal(_msg, m));
}
};
return IterableExtensions.<MessageHandler>findFirst(_sendHandlers, _function);
}
/**
* @param m a {@link Message}
* @return <code>true</code> if this message is an incoming message
*/
public boolean isIncoming(final Message m) {
EObject _eContainer = m.eContainer();
List<Message> _allIncomingMessages = this._roomHelpers.getAllIncomingMessages(((ProtocolClass) _eContainer));
return _allIncomingMessages.contains(m);
}
/**
* @param m a {@link Message}
* @return a string that can be used as identifier for the message. It is prefixed with IN_ or OUT_
* to avoid ambiguities
*/
public String getCodeName(final Message m) {
boolean _isIncoming = this.isIncoming(m);
if (_isIncoming) {
String _name = m.getName();
return ("IN_" + _name);
} else {
String _name_1 = m.getName();
return ("OUT_" + _name_1);
}
}
/**
* @param ac an {@link ActorClass}
* @return <code>true</code> if an operation named 'stop' is defined with a void argument list and
* void return type
*/
public boolean overridesStop(final ActorClass ac) {
boolean _or = false;
EList<StandardOperation> _operations = ac.getOperations();
final Function1<StandardOperation, Boolean> _function = new Function1<StandardOperation, Boolean>() {
public Boolean apply(final StandardOperation e) {
boolean _and = false;
boolean _and_1 = false;
String _name = e.getName();
boolean _equals = Objects.equal(_name, "stop");
if (!_equals) {
_and_1 = false;
} else {
EList<VarDecl> _arguments = e.getArguments();
boolean _isEmpty = _arguments.isEmpty();
_and_1 = _isEmpty;
}
if (!_and_1) {
_and = false;
} else {
RefableType _returnType = e.getReturnType();
boolean _equals_1 = Objects.equal(_returnType, null);
_and = _equals_1;
}
return Boolean.valueOf(_and);
}
};
boolean _exists = IterableExtensions.<StandardOperation>exists(_operations, _function);
if (_exists) {
_or = true;
} else {
boolean _and = false;
ActorClass _actorBase = ac.getActorBase();
boolean _notEquals = (!Objects.equal(_actorBase, null));
if (!_notEquals) {
_and = false;
} else {
ActorClass _actorBase_1 = ac.getActorBase();
boolean _overridesStop = this.overridesStop(_actorBase_1);
_and = _overridesStop;
}
_or = _and;
}
return _or;
}
public BasicEList<AbstractInstance> getAllSubInstances(final StructureInstance ssi) {
final BasicEList<AbstractInstance> result = new BasicEList<AbstractInstance>();
final TreeIterator<EObject> it = ssi.eAllContents();
while (it.hasNext()) {
{
final EObject obj = it.next();
if ((obj instanceof AbstractInstance)) {
result.add(((AbstractInstance) obj));
}
}
}
return result;
}
public String getPortClassName(final EObject p) {
if (p instanceof Port) {
return _getPortClassName((Port)p);
} else if (p instanceof SAP) {
return _getPortClassName((SAP)p);
} else if (p instanceof SPP) {
return _getPortClassName((SPP)p);
} else if (p instanceof ExternalPort) {
return _getPortClassName((ExternalPort)p);
} else if (p instanceof ServiceImplementation) {
return _getPortClassName((ServiceImplementation)p);
} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(p).toString());
}
}
}