Commit c64521a2 authored by Liana Soima's avatar Liana Soima
Browse files

Merge branch 'master' of https://git.fortiss.org/af3/af3.git into 3979

parents 97c1902e 5743242f
ComponentControllerFactory.java a5feb78f57aee4a8206866ef2dc6ca13bb145305 GREEN
ComponentModelFactory.java 9141373b9498b8e947ef1ca8921128bdf66ec308 GREEN
ComponentStructureFXEditor.java c9016fd1b30ee8ed98cace186615c03ccb894abc GREEN
ComponentStructureFXEditor.java f7129096fe9e509f199d07f2db597dac8297a3a2 GREEN
ComponentStructureFXEditorBinding.java 19ca73be6a4ea974994d26db537329878748b20d GREEN
ComponentVisualFactory.java c784b5e87c08abc9a3e201c11bc08b93fce20f6a GREEN
......@@ -45,5 +45,34 @@ public class ComponentStructureFXEditor extends LWFXEFEditorBase<Component> {
DiagramViewerFeatures features = viewer.getFeatures();
features.setIndicatorSpacing(new Dimension2D(12, 12));
features.setBackgroundColor(LIGHTGRAY);
features.setHelpText(MANUAL_LAYOUT + "\n" + BENDPOINT_CREATION + "\n\n" + AUTO_LAYOUT +
"\n\n" + MODEL_CREATION + "\n");
}
/** Manual bendpoint creation help text. */
private static final String MANUAL_LAYOUT = "Manual layout:\n" +
"\t- Use the arrow keys to move components or ports into the desired position.";
/** Bendpoint creation on channel. */
private static final String BENDPOINT_CREATION = "\t- Channel Bendpoint creation:\n" +
"\t\t* Ctrl+left click on a channel to create a bendpoint.\n" +
"\t\t* Bendpoint can be moved by left click+drag.\n" +
"\t\t* Bendpoint can be removed by ctrl+right click.";
/** Auto layout triggering. */
private static final String AUTO_LAYOUT = "Auto layout:\n" +
"\t- Right click in the background of the editor opens the context menu with the auto layout feature.\n" +
"\t- If selected, the components on the current hierarchy level are automatically layouted.";
/** Creation of model elements */
private static final String MODEL_CREATION = "Model element creation:\n" +
"\t- The \"Model Elements\" view on the right, next to the editor, shows all model elements which can be created.\n" +
"\t- By dragging (click+drag) one model element into the editor, the element is created.\n" +
"\t- Alternative for component and ports:\n" +
"\t\t* Right click in the background of the editor or on a component opens the context menu.\n" +
"\t\t* In the \"New..\" sub-menu, components and ports can be created.\n" +
"\t- Channel creation:\n" +
"\t\t* Move the mouse close to a port. The cursor will change to a cross.\n" +
"\t\t* Start dragging (click+drag). Possible connection targets are now highlighted green.\n" +
"\t\t* Enable \"Interactive Area Shading\" in the context menu to get a hint of the size of dragging areas around ports.\n";
}
CCodeGeneratorEasyStartMenu.java aee60ea30cbe51832305ffd448cabc4fafab4452 GREEN
CGeneratorExecutionTarget.java 270fd30aaa67a294fd2bf4585044b46a54ee907f GREEN
FMUGeneratorEasyStartMenu.java 4c2ae30d89d32bb045affa580c052db467c3d35d GREEN
FMUGeneratorExecutionTarget.java 5f9d46042f23a92e0775bdca5ebb3c99b735ee40 GREEN
FMUGeneratorExecutionTarget.java a2075edc7fc987934232228ebbb86997b84741fc GREEN
JavaCodeGeneratorEasyStartMenu.java 08a5ef75fe3ff45840c1cf9e705cb226a1232efb GREEN
JavaGeneratorExecutionTarget.java dba521d1b700365c0522b7c70e49653fcced66cb GREEN
......@@ -21,7 +21,6 @@ import static java.nio.file.Files.createTempDirectory;
import static org.apache.commons.io.FileUtils.deleteDirectory;
import static org.apache.commons.lang.ArrayUtils.addAll;
import static org.eclipse.core.runtime.FileLocator.resolve;
import static org.eclipse.jface.dialogs.MessageDialog.openInformation;
import static org.eclipse.ui.PlatformUI.getWorkbench;
import static org.fortiss.af3.expression.utils.DataDictionaryUtils.findDataDictionary;
import static org.fortiss.af3.generator.common.textgen.c.FMUModelDescriptionTextGenerator.fmuArchiveToXML;
......@@ -32,6 +31,7 @@ import static org.fortiss.tooling.base.utils.SystemUtils.isMacOSXPlatform;
import static org.fortiss.tooling.base.utils.SystemUtils.isOs64BitArch;
import static org.fortiss.tooling.base.utils.SystemUtils.isWindowsPlatform;
import static org.fortiss.tooling.kernel.ui.util.MessageUtilsExtended.showErrorInUIThread;
import static org.fortiss.tooling.kernel.ui.util.MessageUtilsExtended.showInfoInUIThread;
import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
import static org.fortiss.tooling.kernel.utils.ResourceUtils.getResourceURI;
......@@ -110,7 +110,6 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
FMUArchivePackage fmuSource = (FMUArchivePackage)executable.getExecutableObject();
ExecutionConfiguration config = executable.getConfiguration();
Shell currentShell = getWorkbench().getActiveWorkbenchWindow().getShell();
DataDictionary dd = findDataDictionary(((EObject)executable.getSource()));
Double samplingTime = null;
IResource targetFolder;
......@@ -181,7 +180,7 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
error(AF3ComponentUIActivator.getDefault(), cex.getMessage(), cex);
}
if(config != null) {
openInformation(currentShell, "Successful FMU export",
showInfoInUIThread("[Success: FMI export]",
fmuSource.getModelDescription().getName() + ".fmu was successfuly generated!");
}
}
......@@ -353,7 +352,6 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
* Needed since a runtime execution blocks when the limited size output buffer is full.
* Therefore we need to concurrently read from BOTH the error and the output stream.
*/
// TODO
@SuppressWarnings("javadoc")
private static final class InputStreamConsumer implements Callable<List<String>> {
InputStream s;
......
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="res"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="res"/>
<classpathentry exported="true" kind="lib" path="lib/xchart-3.5.2.jar"/>
<classpathentry exported="true" kind="lib" path="lib/coe-1.0.6.jar"/>
<classpathentry kind="output" path="build"/>
</classpath>
......@@ -15,5 +15,6 @@ Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-Vendor: fortiss GmbH
Bundle-ClassPath: .,
lib/xchart-3.5.2.jar
lib/xchart-3.5.2.jar,
lib/coe-1.0.6.jar
Eclipse-BundleShape: dir
CosimulationConfigurationsDialog.java 9fcc43de9ff6ee40b7cb9136155ba937e65b12bb GREEN
CosimulatorGraphGenerator.java 3f786448ab2d977ab9b855d09289df6b6eef61c1 GREEN
CosimulatorGraphGenerator.java dfbe726adbe6acdf66556c2c7b2d45145a286616 GREEN
FMUSimulatorEasyStartMenu.java d11e36db19e4e46b9f662f6e1d2d762bf0a2c67b GREEN
FMUSimulatorExecutionTarget.java e4985e5a691a851db84eac6b015b68b8c15de681 GREEN
FMUSimulatorExecutionTarget.java f792d051c0bd08050bf6367f0e958eb0f5a96e22 GREEN
......@@ -15,6 +15,7 @@
+--------------------------------------------------------------------------*/
package org.fortiss.af3.cosimulation.ui.simulator;
import static java.io.File.separator;
import static java.lang.Double.parseDouble;
import static java.util.Arrays.asList;
import static javax.swing.SwingUtilities.invokeLater;
......@@ -75,8 +76,8 @@ public class CosimulatorGraphGenerator {
String line = "";
String targetFolder = getAF3EclipseProject().getLocation().toOSString();
for(String portName : portsToDisplay) {
try(BufferedReader fileReader =
new BufferedReader(new FileReader(targetFolder + "\\" + rootName + ".csv"))) {
try(BufferedReader fileReader = new BufferedReader(
new FileReader(targetFolder + separator + rootName + ".csv"))) {
line = fileReader.readLine();
String[] tokens = line.split(";");
int timeIndex = asList(tokens).indexOf("time");
......
......@@ -15,21 +15,17 @@
+--------------------------------------------------------------------------*/
package org.fortiss.af3.cosimulation.ui.simulator;
import static java.lang.Runtime.getRuntime;
import static java.io.File.separator;
import static java.lang.Thread.sleep;
import static java.util.concurrent.Executors.newFixedThreadPool;
import static org.apache.commons.io.FileUtils.deleteQuietly;
import static org.eclipse.core.runtime.FileLocator.resolve;
import static org.eclipse.jface.dialogs.MessageDialog.openInformation;
import static org.eclipse.ui.PlatformUI.getWorkbench;
import static org.fortiss.af3.component.utils.ComponentArchitectureUtils.createTemporaryComponentArchitecture;
import static org.fortiss.af3.component.utils.ComponentArchitectureUtils.hasReadOnlyBehaviorSpecification;
import static org.fortiss.af3.cosimulation.ui.simulator.CosimulatorGraphGenerator.displayCosimulationResults;
import static org.fortiss.af3.expression.utils.DataDictionaryUtils.findDataDictionary;
import static org.fortiss.af3.project.utils.FileUtils.getAF3EclipseProject;
import static org.fortiss.tooling.base.utils.SystemUtils.isMacOSXPlatform;
import static org.fortiss.tooling.base.utils.SystemUtils.isWindowsPlatform;
import static org.fortiss.tooling.kernel.ui.util.MessageUtilsExtended.showErrorInUIThread;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.copy;
import static org.fortiss.tooling.kernel.utils.ResourceUtils.getResourceURI;
import static org.fortiss.tooling.kernel.utils.TransformationUtils.createTransformedObjectFor;
import java.io.BufferedReader;
......@@ -37,38 +33,42 @@ import java.io.DataOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import org.apache.commons.io.FileUtils;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.fortiss.af3.component.model.Component;
import org.fortiss.af3.component.model.ComponentArchitecture;
import org.fortiss.af3.component.ui.generator.FMUGeneratorExecutionTarget;
import org.fortiss.af3.cosimulation.model.ExternalSimulationConfiguration;
import org.fortiss.af3.cosimulation.model.FMUSpecification;
import org.fortiss.af3.cosimulation.textgen.CosimulationConfigurationTextGenerator;
import org.fortiss.af3.cosimulation.ui.AF3CosimulationUIActivator;
import org.fortiss.af3.expression.model.DataDictionary;
import org.fortiss.af3.generator.common.model.fmu.FMUArchivePackage;
import org.fortiss.af3.project.extension.base.ExecutionTargetBase;
import org.fortiss.af3.project.extension.data.Executable;
import org.fortiss.af3.project.extension.exception.ExecutionFailedException;
import org.fortiss.tooling.kernel.extension.exception.ChainTransformationFailedException;
import org.intocps.orchestration.coe.CoeMain;
import fi.iki.elonen.NanoHTTPD.ResponseException;
/**
* Execution target for the component architecture simulator having at least one component with
* {@link FMUSpecification}.
*
* @author aziz
* @author munaro
*/
public class FMUSimulatorExecutionTarget extends ExecutionTargetBase {
/** To store the process for COE */
private Process process;
/** {@inheritDoc} */
@Override
......@@ -85,89 +85,168 @@ public class FMUSimulatorExecutionTarget extends ExecutionTargetBase {
/** {@inheritDoc} */
@Override
protected void doExecute(Executable executable) {
if(isMacOSXPlatform()) {
showErrorInUIThread("No macOS support for this feature",
"Running a co-simulation is currently not supported on macOS.");
return;
}
// Thread pool for running the COE
ExecutorService executorService = newFixedThreadPool(1);
Shell currentShell = getWorkbench().getActiveWorkbenchWindow().getShell();
// Retrieve information necessary for the simulation
Component rootComponent = ((ComponentArchitecture)executable.getSource()).getTopComponent();
ExternalSimulationConfiguration simConfig =
(ExternalSimulationConfiguration)executable.getExecutableObject();
Component rootComponent = ((ComponentArchitecture)executable.getSource()).getTopComponent();
String tempBuildDirectoryPath = new String();
DataDictionary dd = findDataDictionary(((ComponentArchitecture)executable.getSource()));
try {
final CosimulationConfigurationsDialog parameterDialog =
new CosimulationConfigurationsDialog(simConfig, rootComponent);
parameterDialog.open();
if(!parameterDialog.goAhead) {
return;
}
tempBuildDirectoryPath = Files.createTempDirectory("httpProcessDirectory").toString();
process = runCosimulationServer(tempBuildDirectoryPath);
String parameters = CosimulationConfigurationTextGenerator
.JSONFileContents(rootComponent, simConfig);
for(Component c : rootComponent.getSubComponents()) {
if(!hasReadOnlyBehaviorSpecification(c)) {
ComponentArchitecture compArch =
createTemporaryComponentArchitecture(copy(c), dd);
createTemporaryFMU(compArch, simConfig.getStepSize());
}
// Ask the user for the simulation parameters
String parameters = getParameters(simConfig, rootComponent);
if(parameters == null) {
return;
}
// Run co-simulation as Eclipse job
Job job = new Job("Co-Simulation") {
@Override
protected IStatus run(IProgressMonitor monitor) {
String sessionID =
runCoSimulation(executorService, rootComponent, simConfig, dd, parameters);
cleanUpSimulationEnvironment(executorService, rootComponent, sessionID);
return Status.OK_STATUS;
}
runHTTPCommands(parameters, simConfig, rootComponent.getName());
};
job.setUser(true);
job.schedule();
}
/** Executes the co-simulation. */
private String runCoSimulation(ExecutorService executorService, Component rootComponent,
ExternalSimulationConfiguration simConfig, DataDictionary dd, String parameters) {
// Start the COE
Future<?> runnable = runCosimulationServer(executorService);
if(runnable.isDone()) {
// No need for an additional error message as one will be displayed upon start-up
return null;
}
// Create a COE session
String sessionID = null;
try {
sessionID = createSession();
} catch(IOException | InterruptedException e) {
showErrorInUIThread("[Error: Session creation]", e.getMessage());
return null;
}
// Convert all non-FMU components to FMUs for simulation
try {
createTemporaryFMUs(rootComponent, simConfig, dd);
} catch(ChainTransformationFailedException | ExecutionFailedException e) {
showErrorInUIThread("[Error: FMU export of non-FMU components]", e.getMessage());
return sessionID;
}
// Run the simulation
try {
simulate(sessionID, parameters, simConfig);
} catch(IOException e) {
MessageDialog.openInformation(currentShell, "[I/O Error]",
"Detailed Error: \n" + e.getMessage());
} catch(ChainTransformationFailedException e) {
MessageDialog.openInformation(currentShell,
"[Temporary FMU: Component Architecture to FMUArchivePackage Transformation] Error:",
"Detailed errors:\n" + e.getMessage());
} catch(ExecutionFailedException e) {
MessageDialog.openInformation(currentShell, "[Temporary FMU Execution] Error:",
"Detailed errors:\n" + e.getMessage());
} catch(InterruptedException e) {
MessageDialog.openInformation(currentShell, "[Error]",
"Detailed Error: \n" + e.getMessage());
showErrorInUIThread("[Error: Co-simulation]", e.getMessage());
return sessionID;
}
deleteTemporaryCreatedFMUs(rootComponent);
// Save the results of the simulation
try {
process.destroy();
process.waitFor();
FileUtils.deleteDirectory(new File(tempBuildDirectoryPath));
} catch(Exception e) {
openInformation(currentShell, "[Error]", "Detailed Error: \n" + e.getMessage());
saveResults(sessionID, rootComponent.getName());
} catch(IOException e) {
showErrorInUIThread("[Error: Storing of co-simulation results]", e.getMessage());
return sessionID;
}
// Display the results of the simulation
try {
displayCosimulationResults(simConfig.getPortsToDisplay(), rootComponent.getName());
} catch(IOException e) {
showErrorInUIThread("[Error: Display of co-simulation results ]", e.getMessage());
return sessionID;
}
// Destroy the COE session
try {
destroySession(sessionID);
} catch(IOException e) {
showErrorInUIThread("[Error: Destruction of simulation session]", e.getMessage());
}
return sessionID;
}
/** Removes temporary files and threads created during the co-simulation. */
private void cleanUpSimulationEnvironment(ExecutorService executorService,
Component rootComponent, String sessionID) {
// Delete all FMUs created from non-FMU components
deleteTemporaryCreatedFMUs(rootComponent);
// Delete the working directory
if(sessionID != null) {
deleteQuietly(new File(sessionID));
}
// Shut the COE down
executorService.shutdownNow();
}
/** Exports all non-FMU components below the root component to FMUs for co-simulation. */
private void createTemporaryFMUs(Component rootComponent,
ExternalSimulationConfiguration simConfig, DataDictionary dd)
throws ChainTransformationFailedException, ExecutionFailedException {
for(Component c : rootComponent.getSubComponents()) {
if(!hasReadOnlyBehaviorSpecification(c)) {
ComponentArchitecture compArch = createTemporaryComponentArchitecture(copy(c), dd);
createTemporaryFMU(compArch, simConfig.getStepSize());
}
}
}
// TODO (#3853): Check if we really have to call the 'java' binary
/** Run cosimulation orchestration engine */
private Process runCosimulationServer(String tempBuildDirectoryPath)
throws IOException, InterruptedException {
String jarsFolder = "/res/org/fortiss/af3/cosimulation/ui/jars";
String pluginID = getResourceURI(AF3CosimulationUIActivator.PLUGIN_ID, jarsFolder);
String targetFolder = resolve(new URL(pluginID)).getPath() + "coe.jar";
if(isWindowsPlatform()) {
targetFolder = targetFolder.substring(1);
/** Displays a dialog requesting the user to set the co-simulation parameters. */
private String getParameters(ExternalSimulationConfiguration simConfig,
Component rootComponent) {
CosimulationConfigurationsDialog parameterDialog =
new CosimulationConfigurationsDialog(simConfig, rootComponent);
parameterDialog.open();
String parameters = null;
if(parameterDialog.goAhead) {
parameters = CosimulationConfigurationTextGenerator.JSONFileContents(rootComponent,
simConfig);
}
String[] coe = new String[] {"java", "-jar", targetFolder};
Process process = getRuntime().exec(coe, null, new File(tempBuildDirectoryPath));
Thread.sleep(5000);
return process;
return parameters;
}
/** Runs the cosimulation orchestration engine */
// TODO(#4001): Redirect COE output / Hide COE output from the AF3 console
private Future<?> runCosimulationServer(ExecutorService executorService) {
return executorService.submit(new Runnable() {
@Override
public void run() {
try {
CoeMain.main(null);
} catch(IOException | ResponseException e) {
showErrorInUIThread("[Error: COE server]", e.getMessage());
} catch(InterruptedException e) {
// Thrown whenever one of the initialization or simulation steps is not
// successful. Such errors are handled by the respective methods.
return;
}
}
});
}
/** Delete the FMUs temporarily created for co-simulation */
/** Deletes the FMUs temporarily created for co-simulation */
private void deleteTemporaryCreatedFMUs(Component root) {
for(Component c : root.getSubComponents()) {
if(!hasReadOnlyBehaviorSpecification(c)) {
IResource targetFolder = getAF3EclipseProject();
deleteQuietly(new File(
targetFolder.getLocation().toOSString() + "\\" + c.getName() + ".fmu"));
deleteQuietly(new File(targetFolder.getLocation().toOSString() + separator +
c.getName() + ".fmu"));
}
}
}
/** Generate the FMUs for the provided component architecture */
/** Generates the FMUs for the provided component architecture */
private void createTemporaryFMU(ComponentArchitecture compArch, double stepSize)
throws ChainTransformationFailedException, ExecutionFailedException {
FMUGeneratorExecutionTarget fmuGen = new FMUGeneratorExecutionTarget();
......@@ -179,34 +258,24 @@ public class FMUSimulatorExecutionTarget extends ExecutionTargetBase {
new Executable(compArch, fmuGen, null, executableObject).execute();
}
/** Run the HTTP commands (GET and POST) required to complete the simulation */
private void runHTTPCommands(String parameters, ExternalSimulationConfiguration simConfig,
String rootName) throws IOException {
String sessionID = createSession();
if(sessionID == null) {
return;
}
/** Runs the HTTP commands (GET and POST) required to complete the simulation */
private void simulate(String sessionID, String parameters,
ExternalSimulationConfiguration simConfig) throws IOException {
sendPost("initialize/" + sessionID, parameters);
String urlParameters = "{\"startTime\":" + simConfig.getStartTime() + ",\"endTime\":" +
simConfig.getEndTime() +
",\"reportProgress\":true,\"liveLogInterval\":0,\"logLevels\":{}}";
sendPost("simulate/" + sessionID, urlParameters);
printResultsInFile(sessionID, rootName);
displayCosimulationResults(simConfig.getPortsToDisplay(), rootName);
destroySession(sessionID);
}
/** Retrieve the simulation results and write in file */
private void printResultsInFile(String sessionID, String rootName) throws IOException {
String url = "http://localhost:8082/result/" + sessionID + "/plain";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection)obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
/** Retrieves the simulation results and write in file */
private void saveResults(String sessionID, String rootName) throws IOException {
InputStream inputStream = sendGet("result/" + sessionID + "/plain");
String inputLine;
String targetFolder = getAF3EclipseProject().getLocation().toOSString();
try(BufferedReader in1 = new BufferedReader(new InputStreamReader(con.getInputStream()));
FileWriter fileWriter = new FileWriter(targetFolder + "\\" + rootName + ".csv")) {
try(BufferedReader in1 = new BufferedReader(new InputStreamReader(inputStream));
FileWriter fileWriter =
new FileWriter(targetFolder + separator + rootName + ".csv")) {
while((inputLine = in1.readLine()) != null) {
fileWriter.append(String.valueOf(inputLine.replace(",", ";")));
fileWriter.append("\n");
......@@ -214,36 +283,41 @@ public class FMUSimulatorExecutionTarget extends ExecutionTargetBase {
}
}
/** Create the HTTP session to start the communication over it and return the sessionID */
private String createSession() throws IOException {
String url = "http://localhost:8082/createSession";
/** Creates the co-simulation and return the respective ID. */
private String createSession() throws IOException, InterruptedException {
InputStream inputStream = null;
do {
try {
inputStream = sendGet("createSession");
} catch(IOException e) {
sleep(100);
}
} while(inputStream == null);
StringBuffer response = new StringBuffer();
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection)obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
try(BufferedReader in1 = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
response.append(in1.readLine());
try(BufferedReader in = new BufferedReader(new InputStreamReader(inputStream))) {
response.append(in.readLine());
}
// Extracting the session ID out of the retrieved response from server
return response.toString().substring(14, 50);
}
/** Destroy the HTTP session */
/** Destroys the HTTP session */
private void destroySession(String sessionID) throws IOException {
String url = "http://localhost:8082/destroy/" + sessionID;
sendGet("destroy/" + sessionID);
}
/** Sends GET requests to the COE server. */
private InputStream sendGet(String extension) throws IOException {
String url = "http://localhost:8082/" + extension;
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection)obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.getInputStream();
HttpURLConnection connection = (HttpURLConnection)obj.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
return connection.getInputStream();
}
/**