Statistics
| Branch: | Tag: | Revision:

root / workspace-metamodels / es.uca.modeling.eol.marte.codegen.wsdl / src / es / uca / modeling / eol / marte / codegen / wsdl / handlers / GeneratePerformanceTestsHandler.java @ master

History | View | Annotate | Download (11.4 KB)

1
package es.uca.modeling.eol.marte.codegen.wsdl.handlers;
2

    
3
import java.io.File;
4
import java.io.IOException;
5
import java.net.URISyntaxException;
6
import java.util.Arrays;
7
import java.util.HashMap;
8
import java.util.HashSet;
9
import java.util.Map;
10
import java.util.Set;
11

    
12
import org.apache.xmlbeans.XmlException;
13
import org.eclipse.core.commands.AbstractHandler;
14
import org.eclipse.core.commands.ExecutionEvent;
15
import org.eclipse.core.commands.ExecutionException;
16
import org.eclipse.core.resources.IFile;
17
import org.eclipse.core.resources.IFolder;
18
import org.eclipse.core.resources.IProject;
19
import org.eclipse.core.resources.IProjectDescription;
20
import org.eclipse.core.resources.IWorkspaceRoot;
21
import org.eclipse.core.resources.ResourcesPlugin;
22
import org.eclipse.core.runtime.CoreException;
23
import org.eclipse.core.runtime.IProgressMonitor;
24
import org.eclipse.core.runtime.Path;
25
import org.eclipse.emf.common.util.URI;
26
import org.eclipse.emf.ecore.EPackage;
27
import org.eclipse.emf.ecore.EPackage.Registry;
28
import org.eclipse.emf.ecore.resource.Resource;
29
import org.eclipse.epsilon.common.util.StringUtil;
30
import org.eclipse.epsilon.egl.EglFileGeneratingTemplateFactory;
31
import org.eclipse.epsilon.egl.EglTemplateFactoryModuleAdapter;
32
import org.eclipse.epsilon.egl.util.FileUtil;
33
import org.eclipse.epsilon.emc.emf.EmfModel;
34
import org.eclipse.epsilon.eol.dt.launching.EclipseContextManager;
35
import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
36
import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException;
37
import org.eclipse.jface.viewers.ISelection;
38
import org.eclipse.jface.viewers.IStructuredSelection;
39
import org.eclipse.m2e.core.internal.IMavenConstants;
40
import org.eclipse.papyrus.MARTE.MARTEPackage;
41
import org.eclipse.ui.handlers.HandlerUtil;
42

    
43
import serviceAnalyzer.messageCatalog.ServicesDocument;
44
import es.uca.modeling.eol.marte.codegen.wsdl.Activator;
45
import es.uca.modeling.eol.marte.weaving.wsdl.links.LinksPackage;
46
import es.uca.modeling.eol.marte.weaving.wsdl.links.PerformanceRequirementLink;
47
import es.uca.modeling.eol.marte.weaving.wsdl.links.PerformanceRequirementLinks;
48
import es.uca.webservices.specgen.SpecGenerator;
49
import es.uca.webservices.testgen.TestGeneratorCommand;
50
import es.uca.webservices.testgen.api.generators.GenerationException;
51
import es.uca.webservices.testgen.api.parsers.ParserException;
52
import es.uca.webservices.testgen.parsers.MessageDirection;
53
import es.uca.webservices.wsdl.analyzer.emf.catalog.MessageCatalogPackage;
54
import es.uca.webservices.wsdl.analyzer.emf.catalog.TypeOperation;
55
import es.uca.webservices.wsdl.analyzer.emf.catalog.TypeService;
56

    
57
/**
58
 * Generates a The Grinder basic Jython script and a Velocity data file
59
 * for running performance tests of a web service.
60
 *
61
 * @author Antonio García-Domínguez
62
 */
63
public class GeneratePerformanceTestsHandler extends AbstractHandler {
64

    
65
        @Override
66
        public Object execute(ExecutionEvent event) throws ExecutionException {
67
                ISelection sel = HandlerUtil.getCurrentSelection(event);
68
                if (sel instanceof IStructuredSelection) {
69
                        IStructuredSelection ssel = (IStructuredSelection)sel;
70
                        IFile file = (IFile)ssel.getFirstElement();
71
                        try {
72
                                generatePerformanceTestsFor(file);
73
                        } catch (Exception e) {
74
                                throw new ExecutionException("Error while generating the performance test project", e);
75
                        }
76
                }
77

    
78
                return null;
79
        }
80

    
81
        private void generatePerformanceTestsFor(IFile file) throws URISyntaxException, EolRuntimeException, Exception {
82
                final EmfModel weavingModel = loadWeavingModel(file);
83
                try {
84
                        final PerformanceRequirementLinks allLinks =
85
                                (PerformanceRequirementLinks)weavingModel
86
                                        .getAllOfType("PerformanceRequirementLinks")
87
                                        .iterator().next();
88

    
89
                        final IProject project = createProject(allLinks);
90
                        populateProject(project, weavingModel, allLinks);
91
                        addMavenNature(project, null);
92
                } finally {
93
                        weavingModel.dispose();
94
                }
95
        }
96

    
97
        private IProject createProject(final PerformanceRequirementLinks allLinks) throws CoreException {
98
                final String projectName = allLinks.getEclipseProjectName();
99
                final IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
100
                final IProject project = workspaceRoot.getProject(projectName);
101
                if (!project.exists()) {
102
                        project.create(null);
103
                }
104
                if (!project.isOpen()) {
105
                        project.open(null);
106
                }
107
                return project;
108
        }
109

    
110
        private void populateProject(IProject project, EmfModel weavingModel, PerformanceRequirementLinks allLinks) throws Exception {
111
                generateCode(weavingModel, project.getFile("pom.xml"));
112
                generateCode(weavingModel, createTestResourceFolder(project, "jython").getFile("tests.py"));
113
                generateCode(weavingModel, createTestResourceFolder(project, "config").getFile("grinder.properties"));
114

    
115
                final Set<TypeOperation> operations = collectAllOperations(allLinks);
116
                final Map<Resource, ServicesDocument> emf2XMLBeans = loadAllServiceCatalogs(operations);
117
                final Map<TypeOperation, File> specFiles = generateSpecs(createTestResourceFolder(project, "spec"), operations, emf2XMLBeans);
118
                generateInputs(createTestResourceFolder(project, "velocity/inputs"), allLinks, specFiles);
119
                generateMessageTemplates(createTestResourceFolder(project, "velocity/messages"), operations);
120

    
121
                project.refreshLocal(IProject.DEPTH_INFINITE, null);
122
        }
123

    
124
        private Map<TypeOperation, File> generateSpecs(IFolder folder, final Set<TypeOperation> operations, final Map<Resource, ServicesDocument> emf2XMLBeans)
125
                        throws ParserException, IOException
126
        {
127
                final Map<TypeOperation, File> specFiles = new HashMap<TypeOperation, File>();
128
                final File fFolder = new File(folder.getLocationURI());
129
                final SpecGenerator gen = new SpecGenerator();
130
                gen.setDirection(MessageDirection.IN);
131

    
132
                for (TypeOperation op : operations) {
133
                        // The operation is inside a port, which is inside a service  
134
                        final TypeService service = (TypeService)op.eContainer().eContainer();
135
                        gen.setServiceName(service.getName());
136
                        gen.setOperationName(op.getName());
137

    
138
                        final ServicesDocument sDoc = emf2XMLBeans.get(op.eResource());
139
                        final String spec = gen.generate(sDoc);
140

    
141
                        final File fSpec = new File(fFolder, service.getName() + "-" + op.getName() + ".spec");
142
                        FileUtil.write(fSpec, spec);
143
                        specFiles.put(op, fSpec);
144
                }
145

    
146
                return specFiles;
147
        }
148

    
149
        private Map<Resource, ServicesDocument> loadAllServiceCatalogs(
150
                        final Set<TypeOperation> operations) throws XmlException,
151
                        IOException {
152
                final Map<Resource, ServicesDocument> emf2XMLBeans = new HashMap<Resource, ServicesDocument>();
153
                for (TypeOperation op : operations) {
154
                        final Resource opResource = op.eResource();
155
                        if (!emf2XMLBeans.containsKey(opResource)) {
156
                                final File fResource = new File(opResource.getURI().toFileString());
157
                                final ServicesDocument sDoc = ServicesDocument.Factory.parse(fResource);
158
                                emf2XMLBeans.put(opResource, sDoc);
159
                        }
160
                }
161
                return emf2XMLBeans;
162
        }
163

    
164
        private Set<TypeOperation> collectAllOperations(PerformanceRequirementLinks allLinks) {
165
                // List all selected operations
166
                final Set<TypeOperation> operations = new HashSet<TypeOperation>();
167
                for (PerformanceRequirementLink link : allLinks.getLinks()) {
168
                        operations.add(link.getOperation());
169
                }
170
                return operations;
171
        }
172

    
173
        private void generateInputs(IFolder folder, PerformanceRequirementLinks allLinks, Map<TypeOperation, File> specFiles) throws IOException, ParserException, GenerationException {
174
                final File fFolder = new File(folder.getLocationURI());
175
                for (File specFile : specFiles.values()) {
176
                        final File fInputs = new File(fFolder, specFile.getName().replace(".spec", ".vm"));
177
                        final TestGeneratorCommand cmd = new TestGeneratorCommand();
178
                        cmd.parseArgs(specFile.getAbsolutePath(), allLinks.getNumberInputsOnSpecChanged() + "", "--output", fInputs.getAbsolutePath());
179
                        cmd.run();
180
                }
181
        }
182

    
183
        private void generateMessageTemplates(IFolder folder, Set<TypeOperation> operations) throws IOException {
184
                final File fFolder = new File(folder.getLocationURI());
185
                for (TypeOperation op : operations) {
186
                        final TypeService service = (TypeService)op.eContainer().eContainer();
187
                        final File fTemplate = new File(fFolder, service.getName() + "-" + op.getName() + ".vm");
188
                        final String sTemplate = op.getInput().getTemplate().getValue();
189
                        FileUtil.write(fTemplate, sTemplate);
190
                }
191
        }
192

    
193
        private IFolder createTestResourceFolder(IProject project, String path) throws CoreException {
194
                final IFolder jythonFolder = project.getFolder(new Path("src/test/" + path));
195
                ensureFolderExists(jythonFolder);
196
                return jythonFolder;
197
        }
198

    
199
        private void ensureFolderExists(IFolder f) throws CoreException {
200
                if (f.getParent() instanceof IFolder && !f.getParent().exists()) {
201
                        ensureFolderExists((IFolder)f.getParent());
202
                }
203
                if (!f.exists()) {
204
                        f.create(true, true, null);
205
                }
206
        }
207

    
208
        private void generateCode(EmfModel weavingModel, IFile targetIFile) throws URISyntaxException, EolRuntimeException, Exception {
209
                final String pathToEGL = "/egl/" + targetIFile.getName() + ".egl";
210
                final File targetFile = new File(targetIFile.getLocationURI());
211
                generateCode(weavingModel, pathToEGL, targetFile);
212
        }
213

    
214
        private void generateCode(final EmfModel weavingModel, final String pathToEGL, final File targetFile)
215
                        throws Exception, URISyntaxException, EolRuntimeException
216
        {
217
                // Parse the EGL script
218
                final EglFileGeneratingTemplateFactory factory = new EglFileGeneratingTemplateFactory();
219
                final EglTemplateFactoryModuleAdapter eglModule = new EglTemplateFactoryModuleAdapter(factory);
220
                eglModule.parse(GeneratePerformanceTestsHandler.class.getResource(pathToEGL).toURI());
221

    
222
                // Run it
223
                EclipseContextManager.setup(eglModule.getContext());
224
                eglModule.getContext().getModelRepository().addModel(weavingModel);
225

    
226
                // Save the result to a file
227
                final String result = StringUtil.toString(eglModule.execute());
228
                FileUtil.write(targetFile, result);
229
        }
230

    
231
        private EmfModel loadWeavingModel(final IFile file)        throws EolModelLoadingException, IOException {
232
                // Required in RCP apps: otherwise, the MARTE metamodel won't be found until the EPackage Registr
233
                // view or a Papyrus editor is opened.
234
                preloadEPackageRegistry();
235

    
236
                final EmfModel model = new EmfModel();
237
                model.setModelFileUri(URI.createFileURI(file.getLocation().toFile().getAbsolutePath()));
238
                model.setMetamodelUris(Arrays.asList(LinksPackage.eNS_URI, MessageCatalogPackage.eNS_URI, MARTEPackage.eNS_URI));
239
                model.setName("Weaving");
240
                model.setExpand(true);
241
                model.setCachingEnabled(true);
242
                model.setReadOnLoad(true);
243
                model.setStoredOnDisposal(false);
244
                model.load();
245
                return model;
246
        }
247

    
248
        private void preloadEPackageRegistry() {
249
                final Registry registry = EPackage.Registry.INSTANCE;
250
                final EPackage marteEPackage = registry.getEPackage(MARTEPackage.eNS_URI);
251
                if (marteEPackage == null) {
252
                        final Set<String> urls = new HashSet<String>(registry.keySet());
253
                        for (String url : urls) {
254
                                final EPackage pkg = registry.getEPackage(url);
255
                                if (pkg == null) {
256
                                        Activator.getDefault().logWarning("EPackage for '" + url + "' is null");
257
                                }
258
                        }
259
                }
260
        }
261

    
262
        /**
263
         * Taken from org.eclipse.m2e.core.internal.project.ProjectConfigurationManager, by Sonatype.
264
         */
265
        private void addMavenNature(IProject project, IProgressMonitor monitor) throws CoreException {
266
                if (!project.hasNature(IMavenConstants.NATURE_ID)) {
267
                        IProjectDescription description = project.getDescription();
268
                        String[] prevNatures = description.getNatureIds();
269
                        String[] newNatures = new String[prevNatures.length + 1];
270
                        System.arraycopy(prevNatures, 0, newNatures, 1, prevNatures.length);
271
                        newNatures[0] = IMavenConstants.NATURE_ID;
272
                        description.setNatureIds(newNatures);
273
                        project.setDescription(description, monitor);
274
                }
275
        }
276
}