From a5bc1a6176bd0c7ba90222dc4f8cd0eaac346106 Mon Sep 17 00:00:00 2001
From: Simon Spinner <simon.spinner@uni-wuerzburg.de>
Date: Wed, 1 Jun 2016 21:29:55 +0200
Subject: [PATCH] Support local calls between modules.

---
 .../service/ModelExtractionService.java       | 53 ++++++++++++++++---
 1 file changed, 46 insertions(+), 7 deletions(-)

diff --git a/tools.descartes.prisma.agent.wildfly/src/main/java/tools/descartes/prisma/agent/wildfly/service/ModelExtractionService.java b/tools.descartes.prisma.agent.wildfly/src/main/java/tools/descartes/prisma/agent/wildfly/service/ModelExtractionService.java
index 81bdfcb..2cde662 100644
--- a/tools.descartes.prisma.agent.wildfly/src/main/java/tools/descartes/prisma/agent/wildfly/service/ModelExtractionService.java
+++ b/tools.descartes.prisma.agent.wildfly/src/main/java/tools/descartes/prisma/agent/wildfly/service/ModelExtractionService.java
@@ -422,10 +422,10 @@ public class ModelExtractionService extends AgentController implements Service<M
 		// 4. Now add the called component (if applicable)
 		InterfaceProvidingRole calledProvidingRole = null;
 		RepositoryComponent calledComponent = null;
-		boolean differentApplication = false;
+		boolean differentModule = false;
 		if (callerRequiringRole != null) {
-			differentApplication = isDifferentApplication(incomingCrec, outgoingCrec);
-			calledComponent = createCalledComponent(outgoingCrec, differentApplication);
+			differentModule = isDifferentModule(incomingCrec, outgoingCrec);
+			calledComponent = createCalledComponent(outgoingCrec, differentModule);
 			String calledProvingRoleName;
 			if (calledComponent instanceof CompositeComponent) {
 				calledProvingRoleName = getInterfaceProvidingRoleName(outgoingIrec,
@@ -439,6 +439,16 @@ public class ModelExtractionService extends AgentController implements Service<M
 			calledProvidingRole.setInterface(outgoingInterface);
 			calledProvidingRole = ModelSkeletonUtil.insert(calledComponent.getInterfaceProvidingRoles(),
 					calledProvidingRole);
+
+			if (differentModule && outgoingIrec.getOperation().getProtocol().equals("java")) {
+				// By default, local interface roles are not exposed on the
+				// composite component. However, in certain cases local calls
+				// between modules of the same application may exist. In this
+				// case we explicitly expose this interface here and add the
+				// required ProvidingDelegationConnector.
+				addLocalCallToModule((CompositeComponent) calledComponent, calledProvidingRole, outgoingCrec,
+						outgoingIrec);
+			}
 		}
 
 		// 5. Now wrap the implementation in a composite component (if
@@ -477,7 +487,7 @@ public class ModelExtractionService extends AgentController implements Service<M
 
 			InterfaceRequiringRole remoteRequiringRole = null;
 			if (callerRequiringRole != null) {
-				if (differentApplication) {
+				if (differentModule) {
 					// Only add a interface requiring role to the composite
 					// component if it is a remote call, i.e., a call to another
 					// composite component.
@@ -643,6 +653,35 @@ public class ModelExtractionService extends AgentController implements Service<M
 		}
 	}
 
+	private void addLocalCallToModule(CompositeComponent module, InterfaceProvidingRole externalRole,
+			ComponentRecord callee, InvocationRecord outgoingIrec) {
+		// Add an implementation component representing the component that is
+		// called.
+		BasicComponent calledBasicComponent = RepositoryFactory.eINSTANCE.createBasicComponent();
+		calledBasicComponent.setName(toName(callee.getComponentClass()));
+		calledBasicComponent = ModelSkeletonUtil.insert(skeleton.getRepository().getComponents(), calledBasicComponent);
+
+		// Add an interface providing role
+		String providingPortName = getInterfaceProvidingRoleName(outgoingIrec, "");
+		InterfaceProvidingRole callerProvidingRole = RepositoryFactory.eINSTANCE.createInterfaceProvidingRole();
+		callerProvidingRole.setName(toName(providingPortName));
+		callerProvidingRole.setInterface(externalRole.getInterface());
+		callerProvidingRole = ModelSkeletonUtil.insert(calledBasicComponent.getInterfaceProvidingRoles(),
+				callerProvidingRole);
+
+		// Create the assembly connections inside the module composite
+		// component.
+		AssemblyContext calledAssembly = addAssemblyContext(module, callee, calledBasicComponent);
+
+		ProvidingDelegationConnector providingConnector = RepositoryFactory.eINSTANCE
+				.createProvidingDelegationConnector();
+		providingConnector.setName(toName(calledAssembly.getName()));
+		providingConnector.setOuterInterfaceProvidingRole(externalRole);
+		providingConnector.setInnerInterfaceProvidingRole(callerProvidingRole);
+		providingConnector.setAssemblyContext(calledAssembly);
+		ModelSkeletonUtil.insert(module.getProvidingDelegationConnectors(), providingConnector);
+	}
+
 	private FineGrainedBehavior createComponentInternalBehavior(BasicComponent implementationComponent,
 			InterfaceProvidingRole implementationProvidingRole, Signature signature) {
 		FineGrainedBehavior behavior = ServicebehaviorFactory.eINSTANCE.createFineGrainedBehavior();
@@ -780,10 +819,10 @@ public class ModelExtractionService extends AgentController implements Service<M
 		throw new IllegalStateException("Could not create called component for " + callee.getComponentName());
 	}
 
-	private boolean isDifferentApplication(ComponentRecord caller, ComponentRecord callee) {
-		boolean sameApplication = caller.getApplication().equals(callee.getApplication())
+	private boolean isDifferentModule(ComponentRecord caller, ComponentRecord callee) {
+		boolean sameModule = caller.getApplication().equals(callee.getApplication())
 				&& caller.getModule().equals(callee.getModule());
-		return !sameApplication;
+		return !sameModule;
 	}
 
 	private boolean isJMSComponent(String componentName) {
-- 
GitLab