From be4f78978faba3d3ceb88df02a7f93a2e09ff1e0 Mon Sep 17 00:00:00 2001 From: Kenji Hosokawa Date: Tue, 3 Aug 2021 18:42:39 +0900 Subject: Initial commit Bug-AGL: SPEC-4033 Signed-off-by: Kenji Hosokawa --- .../endpoint/RBAModelServiceDispatcher.xtend | 37 ++ .../rba/tool/editor/endpoint/RBAModelServlet.xtend | 68 ++++ .../tool/editor/endpoint/RBAModelWebModule.xtend | 57 +++ .../tool/editor/endpoint/RBAModelWebSetup.xtend | 48 +++ .../rba/tool/editor/endpoint/ServerLauncher.xtend | 213 +++++++++++ .../endpoint/generator/RBAModelWebGenerator.xtend | 400 +++++++++++++++++++++ .../resource/RBAModelContentTypeProvider.xtend | 15 + .../resource/RBAModelResourceSetProvider.xtend | 23 ++ .../resource/RBAModelWebEncodingProvider.xtend | 16 + .../RBAModelResourceBaseProviderImpl.xtend | 27 ++ .../RBAModelServerResourceHandler.xtend | 287 +++++++++++++++ 11 files changed, 1191 insertions(+) create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelServiceDispatcher.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelServlet.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelWebModule.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelWebSetup.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/ServerLauncher.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/generator/RBAModelWebGenerator.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelContentTypeProvider.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelResourceSetProvider.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelWebEncodingProvider.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/server/persistence/RBAModelResourceBaseProviderImpl.xtend create mode 100644 rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/server/persistence/RBAModelServerResourceHandler.xtend (limited to 'rba.tool.editor.endpoint/src/rba') diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelServiceDispatcher.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelServiceDispatcher.xtend new file mode 100644 index 0000000..067a03b --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelServiceDispatcher.xtend @@ -0,0 +1,37 @@ +package rba.tool.editor.endpoint + +import com.google.inject.Inject +import javax.inject.Singleton +import org.eclipse.xtext.util.internal.Log +import org.eclipse.xtext.web.server.IServiceContext +import org.eclipse.xtext.web.server.InvalidRequestException +import org.eclipse.xtext.web.server.XtextServiceDispatcher +import org.eclipse.xtext.web.server.generator.GeneratorService + +@Log +@Singleton +class RBAModelServiceDispatcher extends XtextServiceDispatcher { + + @Inject + private GeneratorService generatorService; + + override protected createServiceDescriptor(String serviceType, IServiceContext context) { + if (serviceType == "generate-all") { + return getGeneratorAllService(context) + } + super.createServiceDescriptor(serviceType, context) + } + + protected def getGeneratorAllService(IServiceContext context) throws InvalidRequestException { + val document = getDocumentAccess(context) + new ServiceDescriptor => [ + service = [ + try { + generatorService.getResult(document) + } catch (Throwable throwable) { + handleError(throwable) + } + ] + ] + } +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelServlet.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelServlet.xtend new file mode 100644 index 0000000..b543381 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelServlet.xtend @@ -0,0 +1,68 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.endpoint + +import com.google.inject.Injector +import javax.servlet.annotation.WebServlet +import org.eclipse.emf.common.util.URI +import org.eclipse.xtext.resource.IResourceServiceProvider +import org.eclipse.xtext.util.DisposableRegistry +import org.eclipse.xtext.web.server.InvalidRequestException.UnknownLanguageException +import org.eclipse.xtext.web.servlet.HttpServiceContext +import org.eclipse.xtext.web.servlet.XtextServlet +import rba.tool.editor.endpoint.server.persistence.RBAModelResourceBaseProviderImpl +import org.eclipse.xtext.web.server.XtextServiceDispatcher.ServiceDescriptor +import org.eclipse.xtext.web.server.IServiceResult + +/** + * Deploy this class into a servlet container to enable DSL-specific services. + */ +@WebServlet(name='XtextServices', urlPatterns='/xtext-service/*') +class RBAModelServlet extends XtextServlet { + + val serviceProviderRegistry = IResourceServiceProvider.Registry.INSTANCE + + DisposableRegistry disposableRegistry + + override init() { + super.init() + val resourceBaseProvider = new RBAModelResourceBaseProviderImpl('') + new RBAModelWebSetup(resourceBaseProvider).createInjectorAndDoEMFRegistration + } + + override protected getInjector(HttpServiceContext serviceContext) throws UnknownLanguageException { + var IResourceServiceProvider resourceServiceProvider + + val emfURI = URI.createURI('./sample.rba') + val contentType = serviceContext.getParameter('contentType') + if (contentType.nullOrEmpty) { + + resourceServiceProvider = serviceProviderRegistry.getResourceServiceProvider(emfURI) + if (resourceServiceProvider === null) { + if (emfURI.toString.empty) + throw new UnknownLanguageException('''Unable to identify the Xtext language: missing parameter 'resource' or 'contentType'.''') + else + throw new UnknownLanguageException('''Unable to identify the Xtext language for resource emfURI.''') + } + } else { + resourceServiceProvider = serviceProviderRegistry.getResourceServiceProvider(emfURI, contentType) + if (resourceServiceProvider === null) + throw new UnknownLanguageException('''Unable to identify the Xtext language for contentType contentType.''') + } + return resourceServiceProvider.get(Injector) + } + + override protected getEncoding(ServiceDescriptor service, IServiceResult result) { + 'Shift_JIS' + } + + override destroy() { + if (disposableRegistry !== null) { + disposableRegistry.dispose() + disposableRegistry = null + } + super.destroy() + } + +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelWebModule.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelWebModule.xtend new file mode 100644 index 0000000..b0aeab3 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelWebModule.xtend @@ -0,0 +1,57 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.endpoint + +import com.google.inject.Binder +import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor +import org.eclipse.xtext.generator.IGenerator2 +import org.eclipse.xtext.parser.IEncodingProvider +import org.eclipse.xtext.web.server.XtextServiceDispatcher +import org.eclipse.xtext.web.server.model.IWebResourceSetProvider +import org.eclipse.xtext.web.server.persistence.IResourceBaseProvider +import org.eclipse.xtext.web.server.persistence.IServerResourceHandler +import rba.tool.editor.endpoint.generator.RBAModelWebGenerator +import rba.tool.editor.endpoint.resource.RBAModelContentTypeProvider +import rba.tool.editor.endpoint.resource.RBAModelResourceSetProvider +import rba.tool.editor.endpoint.resource.RBAModelWebEncodingProvider +import rba.tool.editor.endpoint.server.persistence.RBAModelServerResourceHandler +import org.eclipse.xtext.web.server.DefaultWebModule + +/** + * Use this class to register additional components to be used within the web application. + */ +@FinalFieldsConstructor +class RBAModelWebModule extends DefaultWebModule { + + val IResourceBaseProvider resourceBaseProvider + + override bindIContentTypeProvider() { + return RBAModelContentTypeProvider + } + + def Class bindIWebResourceSetProvider() { + return RBAModelResourceSetProvider + } + + def void configureResourceBaseProvider(Binder binder) { + if (resourceBaseProvider !== null) binder.bind(IResourceBaseProvider).toInstance(resourceBaseProvider) + } + + def Class bindIServerResourceHandler() { + return RBAModelServerResourceHandler + } + + def Class bindRBAModelServiceDispatcher() { + return RBAModelServiceDispatcher + } + + def Class bindIGenerator2() { + return RBAModelWebGenerator + } + + def Class bindIEncodingProvider() { + return RBAModelWebEncodingProvider + } + +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelWebSetup.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelWebSetup.xtend new file mode 100644 index 0000000..f90e262 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/RBAModelWebSetup.xtend @@ -0,0 +1,48 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.endpoint + +import com.google.inject.Guice +import com.google.inject.Injector +import org.eclipse.emf.ecore.EPackage +import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor +import org.eclipse.xtext.util.Modules2 +import org.eclipse.xtext.web.server.persistence.IResourceBaseProvider +import rba.core.RBACorePackage +import rba.sound.RBASoundPackage +import rba.tool.editor.RBAModelRuntimeModule +import rba.tool.editor.RBAModelStandaloneSetup +import rba.tool.editor.ide.RBAModelIdeModule +import rba.view.RBAViewPackage + +/** + * Initialization support for running Xtext languages in web applications. + */ +@FinalFieldsConstructor +class RBAModelWebSetup extends RBAModelStandaloneSetup { + + val IResourceBaseProvider resourceBaseProvider + + override Injector createInjector() { + val runtimeModule = new RBAModelRuntimeModule() + val ideModule = new RBAModelIdeModule() + val webModule = new RBAModelWebModule(resourceBaseProvider) + return Guice.createInjector(Modules2.mixin(runtimeModule, ideModule, webModule)) + } + + override register(Injector injector) { + + if (!EPackage.Registry.INSTANCE.containsKey("http://www.denso.com/ict/rba/core")) { + EPackage.Registry.INSTANCE.put("http://www.denso.com/ict/rba/core", RBACorePackage.eINSTANCE); + } + if (!EPackage.Registry.INSTANCE.containsKey("http://www.denso.com/ict/rba/view")) { + EPackage.Registry.INSTANCE.put("http://www.denso.com/ict/rba/view", RBAViewPackage.eINSTANCE); + } + if (!EPackage.Registry.INSTANCE.containsKey("http://www.denso.com/ict/rba/sound")) { + EPackage.Registry.INSTANCE.put("http://www.denso.com/ict/rba/sound", RBASoundPackage.eINSTANCE); + } + super.register(injector) + } + +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/ServerLauncher.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/ServerLauncher.xtend new file mode 100644 index 0000000..d689919 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/ServerLauncher.xtend @@ -0,0 +1,213 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.endpoint + +import java.io.IOException +import java.net.InetSocketAddress +import java.nio.file.NoSuchFileException +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.common.util.WrappedException +import org.eclipse.jetty.annotations.AnnotationConfiguration +import org.eclipse.jetty.client.HttpClient +import org.eclipse.jetty.server.Server +import org.eclipse.jetty.webapp.MetaInfConfiguration +import org.eclipse.jetty.webapp.WebAppContext +import org.eclipse.jetty.webapp.WebInfConfiguration +import org.eclipse.jetty.webapp.WebXmlConfiguration +import rba.tool.editor.endpoint.server.persistence.RBAModelResourceBaseProviderImpl + +import java.io.File; +import org.eclipse.jetty.util.log.*; +import java.nio.charset.StandardCharsets; +import java.io.OutputStreamWriter +import java.io.FileOutputStream +import java.io.BufferedReader +import java.io.InputStreamReader +import java.io.FileInputStream +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +/** + * This program starts an HTTP server for testing the web integration of your DSL. + * Just execute it and point a web browser to http://localhost:8080/ + */ +class ServerLauncher { + + private static String HOST_NAME = 'localhost'; + private static int PORT_NUMBER = 18080; + private static String GENERATE_REQUEST_URL = 'http://%s:%d/xtext-service/generate-all?resource=%s'; + + def static void main(String[] args) { + var successFile = new File(new File(ServerLauncher.getProtectionDomain().getCodeSource().getLocation().toURI()).parent + "/" + "success") + if(successFile.exists) + { + successFile.delete + } + System.setProperty("org.eclipse.jetty.util.log.class", NoLogger.name); + + val server = new Server(new InetSocketAddress(HOST_NAME, PORT_NUMBER)) + server.handler = new WebAppContext => [ + resourceBase = '.' + contextPath = "/" + configurations = #[ + new AnnotationConfiguration, + new WebXmlConfiguration, + new WebInfConfiguration, + new MetaInfConfiguration + ] + setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, '.*/rba\\.tool\\.editor\\.web/.*,.*\\.jar') + setInitParameter("org.mortbay.jetty.servlet.Default.useFileMappedBuffer", "false") + ] + + try { + var outputDirStr = new File(ServerLauncher.getProtectionDomain().getCodeSource().getLocation().toURI()).parent; + if(args.length > 1) { + outputDirStr = args.get(1); + } + + var outputDir = new File(outputDirStr); + if (!outputDir.exists()) { + System.err.println("No such file or directory: " + outputDirStr) + System.exit(1) + return; + } + + server.start + + if (args !== null && args.length > 0) { + doRequest(args.get(0)) + } + + server.stop + server.join + + var successFile2 = new File(new File(ServerLauncher.getProtectionDomain().getCodeSource().getLocation().toURI()).parent + "/" + "success") + if(!successFile2.exists) + { + System.exit(1); + } + successFile2.delete + + var srcDir = new File(ServerLauncher.getProtectionDomain().getCodeSource().getLocation().toURI()).parent; + var jsonFile = new File(srcDir + "/template-gen/RBAModel.json"); + var tmpJsonFile = new File(srcDir + "/template-gen/RBAModel.json.tmp"); + jsonFile.renameTo(tmpJsonFile); + + var newJsonFile = new File(srcDir + "/template-gen/RBAModel.json"); + + var in = new BufferedReader(new InputStreamReader(new FileInputStream(tmpJsonFile))); + var writer = new OutputStreamWriter(new FileOutputStream(newJsonFile), StandardCharsets.UTF_8); + var line = ""; + while((line = in.readLine()) !== null) { + writer.write(line); + if(in.ready()){ + writer.write("\n"); + } + } + writer.flush(); + writer.close(); + in.close(); + + tmpJsonFile.delete; + + var targetFile = new File(outputDirStr + "/RBAModel.json"); + if(newJsonFile != targetFile) { + jsonFile.renameTo(targetFile); + } + + System.exit(0); + + } catch (Exception exception) { + System.err.println(exception.message) + System.exit(1) + } + } + + def static void doRequest(String resourceId) { + try { + val uri = URI.createURI(RBAModelResourceBaseProviderImpl.slashify(resourceId, true)) + if (uri === null) + throw new IOException('The requested resource does not exist.') + + val client = new HttpClient(); + client.start(); + val String resourceId_URLEnc = URLEncoder.encode(resourceId, "UTF-8"); + val res = client.GET(String.format(GENERATE_REQUEST_URL, HOST_NAME, PORT_NUMBER, resourceId_URLEnc)) + client.stop() + } catch (NoSuchFileException exception) { + exception.printStackTrace + System.err.format("%s: no such file or directory%n", resourceId); + throw exception.cause + } catch (IOException exception) { + System.err.format("%s%n", exception); + throw exception.cause + } catch (WrappedException exception) { + throw exception.cause + } + } +} + +class NoLogger implements Logger { + + override debug(Throwable thrown) { + return + } + + override debug(String arg0, Object... arg1) { + return + } + + override debug(String arg0, long arg1) { + return + } + + override debug(String arg0, Throwable arg1) { + return + } + + override getLogger(String name) { + return this + } + + override getName() { + return "nothing" + } + + override ignore(Throwable ignored) { + return + } + + override info(Throwable thrown) { + return + } + + override info(String arg0, Object... arg1) { + return + } + + override info(String arg0, Throwable arg1) { + return + } + + override isDebugEnabled() { + return false + } + + override setDebugEnabled(boolean enabled) { + return + } + + override warn(Throwable thrown) { + return + } + + override warn(String arg0, Object... arg1) { + return + } + + override warn(String arg0, Throwable arg1) { + return + } + +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/generator/RBAModelWebGenerator.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/generator/RBAModelWebGenerator.xtend new file mode 100644 index 0000000..2a9d1e7 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/generator/RBAModelWebGenerator.xtend @@ -0,0 +1,400 @@ +package rba.tool.editor.endpoint.generator + +import java.util.List +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import groovy.lang.Binding; +import groovy.util.GroovyScriptEngine; +import org.codehaus.groovy.control.CompilerConfiguration; + +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.xtext.generator.AbstractGenerator +import org.eclipse.xtext.generator.IFileSystemAccess2 +import org.eclipse.xtext.generator.IGeneratorContext + +import rba.tool.editor.model.manager.ResourceManager +import rba.tool.core.sort.SortValueManager; + +import rba.core.Allocatable; +import rba.view.Area; +import rba.sound.Zone; +import rba.view.AreaSet; +import rba.sound.ZoneSet; +import rba.core.Content; +import rba.view.ViewContent; +import rba.view.ViewContentSet; +import rba.sound.SoundContent; +import rba.sound.SoundContentSet; +import rba.core.State; +import rba.core.Scene; +import rba.view.Size; +import rba.view.Display +import rba.view.PositionContainer +import rba.core.Package; +import rba.core.Constraint; +import rba.core.Variable; +import rba.core.SetOfOperator; + +import rba.tool.editor.generator.z3.SortValueCodeGenerationSupporter; +import rba.tool.core.sort.ISortValueCalculation; + +import java.io.OutputStreamWriter +import java.io.FileOutputStream +import java.nio.charset.StandardCharsets +import rba.tool.core.sort.SortValue +import java.util.Arrays +import org.eclipse.emf.ecore.EObject +import java.util.ArrayList +import org.eclipse.emf.ecore.util.EContentsEList +import org.eclipse.emf.ecore.EReference +import org.eclipse.emf.common.util.EList + +class RBAModelWebGenerator extends AbstractGenerator { + + override doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { + var isError = false + + for(r : resource.resourceSet.resources) + { + for(eo : r.allContents.toIterable) + { + //to resolve cross reference + var EContentsEList.FeatureIterator fi = eo.eCrossReferences.iterator as EContentsEList.FeatureIterator; + while( fi.hasNext() ) { + var EObject o = fi.next(); + var EReference er = fi.feature() as EReference; + if (er.getEOpposite() !== null) { + //System.out.println(eo + "'s " + er.name + " --> " + o); + if (er.getEOpposite().isMany) { + var oppositeList =(o.eGet(er.getEOpposite()) as EList); + if (!oppositeList.contains(eo)) { + oppositeList.add(eo) + } + } else { + + } + } + } + } + + for(w : r.warnings) + { + System.err.println(w.toString) + } + for(e : r.errors) + { + var filename = new File(r.URI.toFileString).name; + System.err.println("Error: " + filename + ":" + e.line + " " + e.message) + isError = true + } + } + + if(isError) + { + return; + } + + runScript(WorkingDirectory.get() + "/script", "TemplateGenerator.groovy", resource.resourceSet); + } + + def void runScript(String scriptDir, String fileName, ResourceSet resourceSet) { + try { + var dir = new File(scriptDir) + var file = new File(scriptDir + "/" + fileName) + if (!dir.exists() || !file.exists()) { + return; + } + var e = new GroovyScriptEngine(#[scriptDir], getClass().getClassLoader()) + var config = new CompilerConfiguration() + config.setTargetDirectory(scriptDir) + var RunScriptInternalUtil util = new RunScriptInternalUtil() + util.setResourceManager(ResourceManager.INSTANCE) + util.setResourceSet(resourceSet) + util.loadZ3Lib(); + util.calculate(); + var Binding bind = new Binding() + bind.setVariable("location", scriptDir) + bind.setVariable("util", util) + e.setConfig(config) + var start_time = System.currentTimeMillis() + e.run(fileName, bind) + var finish_time = System.currentTimeMillis() + removeClassFiles(scriptDir) + new File(WorkingDirectory.get() + "/" + "success").createNewFile + } catch (Throwable e) { + e.printStackTrace() + System.err.println("error:" + e.getMessage()) + } + + } + + def static void removeClassFiles(String folderPath) { + var File folder = new File(folderPath) + for (File file : folder.listFiles()) { + var pattern = Pattern.compile(".class$") + var Matcher m = pattern.matcher(file.getName()) + if (file.isFile() && m.find()) { + file.delete() + } + } + } + +} + +class WorkingDirectory { + def static String get() { + return new File(RBAModelWebGenerator.getProtectionDomain().getCodeSource().getLocation().toURI()).parent; + } +} + +class RunScriptInternalUtil { + ResourceSet resourceSet; + ResourceManager resourceManager + private static SortValueCodeGenerationSupporter generationSupporter = new SortValueCodeGenerationSupporter(); + + private SortValue areaZorderSortValue = new SortValue(); + private SortValue visibilitySortValue = new SortValue(); + private SortValue csPrioritySortValue = new SortValue(); + + static String OS_NAME = System.getProperty("os.name").toLowerCase(); + def boolean isLinux() { + return OS_NAME.startsWith("linux"); + } + def boolean isWindows() { + return OS_NAME.startsWith("windows"); + } + + def protected void setSortValueManager(SortValueManager sortValueManager) { + this.sortValueManager = sortValueManager + } + + def protected void setResourceManager(ResourceManager resourceManager) { + this.resourceManager = resourceManager + } + + def protected void setResourceSet(ResourceSet resourceSet) { + this.resourceSet = resourceSet + } + + def boolean loadZ3Lib() { + var z3Path = WorkingDirectory.get(); + + if(isLinux()) { + z3Path = z3Path + "/lib/linux/z3/bin"; + } + else if(isWindows()) { + z3Path = z3Path + "/lib/windows/z3"; + } + else { + print("error: Not supported OS"); + return false; + } + + try { + loadLibs(z3Path); + addLibraryPath(z3Path); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + def void loadLibs(String z3Path) throws Exception { + if(isLinux()) { + System.load(z3Path + "/libz3.so"); + System.load(z3Path + "/libz3java.so"); + } + else if(isWindows()) { + System.load(z3Path + "/Microsoft.Z3.dll"); + System.load(z3Path + "/msvcr110.dll"); + System.load(z3Path + "/msvcp110.dll"); + System.load(z3Path + "/vcomp110.dll"); + System.load(z3Path + "/libz3.dll"); + System.load(z3Path + "/libz3java.dll"); + } + } + + def void addLibraryPath(String pathToAdd) throws Exception { + val usrPathsField = ClassLoader.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + val paths = usrPathsField.get(null) as String[]; + for (String path : paths) { + if (path.equals(pathToAdd)) { + return; + } + } + val newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths.set(newPaths.length - 1, pathToAdd); + usrPathsField.set(null, newPaths); + } + + def void calculate() { + var code = resourceSet.compile.toString(); + val createdFile = new File("./SortValueCalculation.java"); + try { + var writer = new OutputStreamWriter(new FileOutputStream(createdFile), StandardCharsets.UTF_8); + writer.write(code, 0, code.length()); + writer.flush(); + writer.close(); + } + catch(Exception e) { + System.out.println("error: " + e.toString()); + } + + var e = new GroovyScriptEngine("./", getClass().getClassLoader()); + e.loadScriptByName("./SortValueCalculation.java"); + var s = e.getGroovyClassLoader().loadClass("SortValueCalculation"); + + var calc = s.newInstance() as ISortValueCalculation; + calc.setUp(); + areaZorderSortValue.setSortValue(calc.calculateArea_zorder()); + visibilitySortValue.setSortValue(calc.calculateAllocatable_visibility()); + csPrioritySortValue.setSortValue(calc.calculateContentState_priority()); + calc.close(); + + createdFile.delete(); + } + + def compile(ResourceSet resourceSet) ''' + «val allAllocatables = ResourceManager.INSTANCE.getRbaAllocatables(resourceSet)» + + «val allAreas = ResourceManager.INSTANCE.getRbaAreas(resourceSet)» +««« «FOR area : allAreas» +««« «area.name» : [ «FOR content : area.contents»«content.name», «ENDFOR»] +««« «ENDFOR» + «val allContents = ResourceManager.INSTANCE.getRbaContents(resourceSet)» +««« «FOR content : allContents» +««« «content.name» : [ «FOR area : content.allocatable»«area.name», «ENDFOR»] +««« «ENDFOR» + «generationSupporter.generate(allContents, allAllocatables, allAreas)» + ''' + + def void print(String message) { + System.out.println(message) + } + + def List getAllocatables() { + return resourceManager.getRbaAllocatables(resourceSet) + } + + def List getAreas() { + return resourceManager.getRbaAreas(resourceSet) + } + + def List getZones() { + return resourceManager.getRbaZones(resourceSet) + } + + def List getAreaSets() { + return resourceManager.getRbaAreaSets(resourceSet) + } + + def List getZoneSets() { + return resourceManager.getRbaZoneSets(resourceSet) + } + + def List getContents() { + return resourceManager.getRbaContents(resourceSet) + } + + def List getViewContents() { + return resourceManager.getRbaViewContents(resourceSet) + } + + def List getViewContentSets() { + return resourceManager.getRbaViewContentSets(resourceSet) + } + + def List getSoundContents() { + return resourceManager.getRbaSoundContents(resourceSet) + } + + def List getSoundContentSets() { + return resourceManager.getRbaSoundContentSets(resourceSet) + } + + def List getStates() { + return resourceManager.getRbaState(resourceSet) + } + + def List getScenes() { + return resourceManager.getRbaScenes(resourceSet) + } + + def List getSizes() { + return resourceManager.getRbaSizes(resourceSet) + } + + def List getDisplays() { + return resourceManager.getRbaDisplays(resourceSet) + } + + def List getPositionContainers() { + return resourceManager.getRbaPositionContainers(resourceSet) + } + + def List getPackages() { + return resourceManager.getRbaPackages(resourceSet) + } + + def List getRootPackages() { + return resourceManager.getRbaRootPackages(resourceSet) + } + + def List getConstraints() { + return resourceManager.getRbaConstraints(resourceSet) + } + + def List getOnlineConstraints() { + return resourceManager.getRbaOnlineConstraints(resourceSet) + } + + def List getOfflineConstraints() { + return resourceManager.getRbaOfflineConstraints(resourceSet) + } + + def List getViewConstraints() { + return resourceManager.getRbaViewConstraints(resourceSet) + } + + def List getSoundConstraints() { + return resourceManager.getRbaSoundConstraints(resourceSet) + } + + + def List getVariables() { + return resourceManager.getRbaVariables(resourceSet) + } + + def List getSetOfOperators() { + return resourceManager.getRbaSetOfOperators(resourceSet) + } + + def int getVisibility(String areaName) { + return visibilitySortValue.getValue(areaName); + } + + def int getZorder(String areaName) { + return areaZorderSortValue.getValue(areaName); + } + + def int getPriority(String contentName, String contentStateName) { + return csPrioritySortValue.getValue(contentName + "_" + contentStateName); + } + + def List collect(Class clazz) { + var results = new ArrayList(); + var ite = resourceManager.getRbaAllContents(resourceSet).iterator(); + while (ite.hasNext()) { + var obj = ite.next(); + if (clazz.isAssignableFrom(obj.getClass())) { + results.add(obj as T); + } + } + return results; + } +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelContentTypeProvider.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelContentTypeProvider.xtend new file mode 100644 index 0000000..b089502 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelContentTypeProvider.xtend @@ -0,0 +1,15 @@ +package rba.tool.editor.endpoint.resource + +import org.eclipse.xtext.web.server.generator.DefaultContentTypeProvider +import org.eclipse.xtext.web.server.generator.GeneratorService + +class RBAModelContentTypeProvider extends DefaultContentTypeProvider { + + override getContentType(String fileName) { + if (fileName == GeneratorService.DEFAULT_ARTIFACT) { + return 'text/html'; + } + super.getContentType(fileName); + } + +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelResourceSetProvider.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelResourceSetProvider.xtend new file mode 100644 index 0000000..52b0342 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelResourceSetProvider.xtend @@ -0,0 +1,23 @@ +package rba.tool.editor.endpoint.resource + +import com.google.inject.Inject +import com.google.inject.Provider +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.xtext.web.server.IServiceContext +import org.eclipse.xtext.web.server.model.IWebResourceSetProvider + +class RBAModelResourceSetProvider implements IWebResourceSetProvider { + + static val MULTI_RESOURCE_PREFIX = 'multi-resource' + + @Inject Provider provider + + override get(String resourceId, IServiceContext serviceContext) { + if (resourceId !== null && resourceId.startsWith(MULTI_RESOURCE_PREFIX)) { + val pathEnd = Math.max(resourceId.indexOf('/'), MULTI_RESOURCE_PREFIX.length) + return serviceContext.session.get(ResourceSet -> resourceId.substring(0, pathEnd), [provider.get]) + } else { + return provider.get + } + } +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelWebEncodingProvider.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelWebEncodingProvider.xtend new file mode 100644 index 0000000..42b7034 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/resource/RBAModelWebEncodingProvider.xtend @@ -0,0 +1,16 @@ +package rba.tool.editor.endpoint.resource + +import org.eclipse.emf.common.util.URI +import org.eclipse.xtext.parser.IEncodingProvider +import com.google.inject.Singleton + +@Singleton +class RBAModelWebEncodingProvider extends IEncodingProvider.Runtime { + + override getEncoding(URI uri) { + if (defaultEncoding !== null) + return defaultEncoding; + return 'utf-8'; + } + +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/server/persistence/RBAModelResourceBaseProviderImpl.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/server/persistence/RBAModelResourceBaseProviderImpl.xtend new file mode 100644 index 0000000..02d1519 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/server/persistence/RBAModelResourceBaseProviderImpl.xtend @@ -0,0 +1,27 @@ +package rba.tool.editor.endpoint.server.persistence + +import java.io.File +import org.eclipse.emf.common.util.URI +import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor +import org.eclipse.xtext.web.server.persistence.IResourceBaseProvider + +@FinalFieldsConstructor +class RBAModelResourceBaseProviderImpl implements IResourceBaseProvider { + + val String resourceBase + + override getFileURI(String resourceId) { +// if (resourceId.contains('..')) +// throw new InvalidRequestException.InvalidParametersException('Invalid resource path.') + URI.createURI(slashify(resourceBase + resourceId, true)) + } + + def static String slashify(String resourceId, boolean isDirectory) { + var p = resourceId; + if (File.separatorChar != '/') + p = p.replace(File.separatorChar, '/'); + if (!p.endsWith("/") && isDirectory) + p = p + "/"; + return p; + } +} diff --git a/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/server/persistence/RBAModelServerResourceHandler.xtend b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/server/persistence/RBAModelServerResourceHandler.xtend new file mode 100644 index 0000000..b9e67a9 --- /dev/null +++ b/rba.tool.editor.endpoint/src/rba/tool/editor/endpoint/server/persistence/RBAModelServerResourceHandler.xtend @@ -0,0 +1,287 @@ +package rba.tool.editor.endpoint.server.persistence + +import com.google.inject.Inject +import com.google.inject.Injector +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.OutputStreamWriter +import java.nio.file.attribute.BasicFileAttributes +import java.nio.file.Files +import java.nio.file.FileSystems +import java.nio.file.FileVisitResult +import java.nio.file.NoSuchFileException +import java.nio.file.Path +import java.nio.file.Paths +import java.nio.file.SimpleFileVisitor +import java.text.ParseException +import java.util.ArrayList +import java.util.LinkedHashSet +import java.util.List +import java.util.Set +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.common.util.WrappedException +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.xtext.nodemodel.BidiTreeIterable +import org.eclipse.xtext.nodemodel.INode +import org.eclipse.xtext.nodemodel.impl.CompositeNodeWithSemanticElement +import org.eclipse.xtext.parser.IEncodingProvider +import org.eclipse.xtext.resource.XtextResource +import org.eclipse.xtext.resource.IResourceServiceProvider +import org.eclipse.xtext.web.server.IServiceContext +import org.eclipse.xtext.web.server.model.IWebDocumentProvider +import org.eclipse.xtext.web.server.model.IWebResourceSetProvider +import org.eclipse.xtext.web.server.model.IXtextWebDocument +import org.eclipse.xtext.web.server.persistence.IResourceBaseProvider +import org.eclipse.xtext.web.server.persistence.IServerResourceHandler +import rba.tool.editor.model.manager.ResourceManager +import rba.tool.editor.parser.antlr.RBAModelParser +import rba.core.RuleObject +import rba.core.Tag +import rba.core.Stereotype + +class RBAModelServerResourceHandler implements IServerResourceHandler { + + @Inject IResourceBaseProvider resourceBaseProvider + + @Inject IWebResourceSetProvider resourceSetProvider + + @Inject IWebDocumentProvider documentProvider + + @Inject IEncodingProvider encodingProvider + + override get(String resourceId, IServiceContext serviceContext) throws IOException { + try { + var resourceUris = new LinkedHashSet + val uri = resourceBaseProvider.getFileURI(resourceId) + if (uri === null) + throw new IOException('The requested resource does not exist.') + + var path = Paths.get(uri.path); + var realPath = path.toRealPath(#[]) + resourceUris.clear + resourceUris.addAll(Files.walk(realPath).filter(p|p.toString().endsWith(".rba")).map(p|URI.createFileURI(p.toString)).iterator.toSet) + + if (resourceUris === null || resourceUris.size === 0) + throw new IOException('The requested resource does not exist.') + + var appliedFolder = createAppliedFolder(realPath) + var appliedUriSet = new LinkedHashSet + + var resourceSet = resourceSetProvider.get("./.applied", serviceContext) + for (resourceUri : resourceUris) { + resourceSet.getResource(resourceUri, true) + } + + var stereotypeFolder = new File(appliedFolder, "stereotype") + stereotypeFolder.mkdir + appliedUriSet.clear + for (resource : resourceSet.resources) { + val parseResult = doRBAParse(resource.URI) + val allStereotypes = ResourceManager.INSTANCE.getRbaStereotypes(resourceSet) + val root = parseResult.rootNode + var completeContentBuf = new StringBuffer(root.text) + var appliedTagList = new LinkedHashSet + var appliedLength = 0 + + for(node : root.asTreeIterable) { + var element = node.semanticElement + if( (node instanceof CompositeNodeWithSemanticElement) + && (element instanceof RuleObject)) { + val tagNodes = getTagNodes(node.asTreeIterable) + val appliedOffset = if(tagNodes.empty) 0 else tagNodes.last.endOffset + 1 + var appliedBuf = new StringBuffer("") + + for(tagNode : tagNodes) { + var tagElement = tagNode.semanticElement as Tag + + for(stereoType : allStereotypes) { + if(!appliedTagList.contains(tagElement) + && isValidStereotype(tagElement, stereoType, element as RuleObject)) { + appliedTagList.add(tagElement) + val expanded = doExpandStereotype(stereoType, tagElement) + appliedBuf.append(expanded) + } + } + + if(appliedBuf.length > 0) { + completeContentBuf.insert(appliedOffset + appliedLength, appliedBuf) + appliedLength += appliedBuf.length + } + } + } + } + + completeContentBuf = guillemetize(completeContentBuf) + + var sourceFile = new File(resource.URI.path) + var stereotypeAppliedFile = new File(stereotypeFolder, sourceFile.name) + var stereotypeAppliedOStream = new FileOutputStream(stereotypeAppliedFile, false) + stereotypeAppliedOStream.write(completeContentBuf.toString.getBytes("UTF-8")) + stereotypeAppliedOStream.close + + appliedUriSet.add(URI.createFileURI(stereotypeAppliedFile.path)) + } + + resourceSet = resourceSetProvider.get("./.applied", serviceContext) + for (resourceUri : appliedUriSet) { + resourceSet.getResource(resourceUri, true) + } + + val firstResource = resourceSet.resources.get(0) as XtextResource + return documentProvider.get(resourceId, serviceContext) => [ + setInput(firstResource) + ] + } catch (NoSuchFileException exception) { + System.err.format("%s: no such file or directory%n", exception.file); + throw exception.cause + } catch (IOException exception) { + System.err.format("%s%n", exception); + throw exception.cause + } catch (WrappedException exception) { + throw exception.cause + } + } + + override put(IXtextWebDocument document, IServiceContext serviceContext) throws IOException { + try { + val uri = resourceBaseProvider.getFileURI(document.resourceId) + val outputStream = document.resource.resourceSet.URIConverter.createOutputStream(uri) + val writer = new OutputStreamWriter(outputStream, encodingProvider.getEncoding(uri)) + writer.write(document.text) + writer.close + } catch (WrappedException exception) { + throw exception.cause + } + } + + def createAppliedFolder(Path realPath) { + var appliedFolder = new File(realPath.parent.toFile, ".applied_JSONGen") + + if(appliedFolder.exists) { + Files.walkFileTree(FileSystems.getDefault.getPath(appliedFolder.path), new SimpleFileVisitor() { + override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException + { + Files.delete(file) + return FileVisitResult.CONTINUE + } + + override public FileVisitResult postVisitDirectory(Path dir, IOException e) + throws IOException + { + if(e === null) { + Files.delete(dir) + return FileVisitResult.CONTINUE + } + else { + throw e + } + } + }) + } + + appliedFolder.mkdir + + return appliedFolder + } + + def doTemplateParse(Set uriSet, ResourceSet resourceSet) throws ParseException { + for (resourceUri : uriSet) { + resourceSet.getResource(resourceUri, true) + } + + for (resource : resourceSet.resources) { + val errors = resource.errors + for (error : errors) { + var uri = resource.URI + var filename = uri.segment(uri.segmentCount - 1) + var buf = new StringBuffer(filename + "(l." + error.line + ": col." + error.column + "): error: "+ error.message + ".") + System.err.println(buf.toString) + throw new ParseException(buf.toString, error.line) + } + } + + return resourceSet + } + + def doRBAParse(URI resourceUri) { + var resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(resourceUri) + var injector = resourceServiceProvider.get(Injector) + var modelParser = injector.getInstance(RBAModelParser) + + return modelParser.parse(Files.newBufferedReader(Paths.get(resourceUri.path))) + } + + def expandCore(String templated, String[] arguments, String[] values, boolean trim) { + var expanded = templated + + expanded = expanded.replace("@END@", "") + expanded = expanded.replace("@BEGIN@", "") + if(trim) { + expanded = expanded.trim + } + + if( (arguments.size > 0) + && (values.size > 0)) { + for(index : 0..(values.size - 1)) { + var value = values.get(index) + value = value.replaceAll("\"", "") + expanded = expanded.replace("@{" + arguments.get(index) + "}", value) + } + } + + return expanded + } + + def doExpandStereotype(Stereotype stereotype, Tag tag) { + var variables = new ArrayList + if(stereotype.variables.size > 0) { + for(index : 0..(stereotype.variables.size - 1)) { + variables.add(stereotype.variables.get(index).name) + } + } + return expandCore(stereotype.bodyText, variables, tag.values, false) + } + + + def getTagNodes(BidiTreeIterable tree) { + val nodeList = new ArrayList + for(INode node : tree) { + if( (node instanceof CompositeNodeWithSemanticElement) + && (node.semanticElement instanceof Tag)) { + nodeList.add(node) + } + } + + return nodeList + } + + def isValidStereotype(Tag tag, Stereotype stereotype, RuleObject element) { + if( !(stereotype.name.equals(tag.name)) + || !(element.eClass.name.equalsIgnoreCase(stereotype.targetModelName))) { + return false; + } else if((tag.values !== null) + && (stereotype.variables !== null) + && (stereotype.variables.size == tag.values.size)) { + return true; + } else if((tag.values === null) + && (stereotype.variables.size === 0)) { + return true; + } + return false; + } + + def guillemetize(StringBuffer buf) { + val BRACKET_OPEN = "<<" + val BRACKET_CLOSE = ">>" + val GUILLEMET_OPEN = "«" + val GUILLEMET_CLOSE = "»" + var guillemetized = buf.toString + + guillemetized = guillemetized.replace(BRACKET_OPEN, GUILLEMET_OPEN) + guillemetized = guillemetized.replace(BRACKET_CLOSE, GUILLEMET_CLOSE) + + return buf.delete(0, buf.length).insert(0, guillemetized) + } +} -- cgit 1.2.3-korg