| /** |
| * Copyright (c) 2020 Eclipse contributors and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| */ |
| package org.eclipse.justj.codegen.model.util; |
| |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.io.PrintStream; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.LinkedHashMap; |
| import java.util.LinkedHashSet; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.ProgressMonitorWrapper; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.emf.common.CommonPlugin; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.URIConverter; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.equinox.app.IApplication; |
| import org.eclipse.equinox.app.IApplicationContext; |
| import org.eclipse.justj.codegen.model.Copyrightable; |
| import org.eclipse.justj.codegen.model.JVM; |
| import org.eclipse.justj.codegen.model.Model; |
| import org.eclipse.justj.codegen.model.ModelPackage; |
| import org.eclipse.justj.codegen.model.Phase; |
| import org.eclipse.justj.codegen.model.Touchable; |
| import org.eclipse.justj.codegen.model.Touchpoint; |
| import org.eclipse.justj.codegen.model.Variant; |
| |
| |
| public class Generator |
| { |
| private final Model model; |
| |
| private final URI target; |
| |
| private final Path localCache; |
| |
| private final URIConverter uriConverter; |
| |
| public static void main(String[] args) throws IOException |
| { |
| Path path = Paths.get(args[0]); |
| Path realPath = path.toRealPath(); |
| Generator generator = new Generator(URI.createFileURI(realPath.toString())); |
| generator.generate(new ProgressMonitorWrapper(new NullProgressMonitor()) |
| { |
| @Override |
| public void subTask(String name) |
| { |
| super.subTask(name); |
| System.out.println(name); |
| } |
| }); |
| } |
| |
| public Generator(URI source) throws IOException |
| { |
| ModelPackage.eINSTANCE.eClass(); |
| |
| ResourceSet resourceSet = new ResourceSetImpl(); |
| uriConverter = resourceSet.getURIConverter(); |
| resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("jregen", new ModelResourceFactoryImpl()); |
| |
| Resource resource = resourceSet.getResource(source, true); |
| model = (Model)resource.getContents().get(0); |
| this.target = computeTarget(model); |
| this.localCache = Reconciler.computeLocalCache(model); |
| } |
| |
| public Generator(Model model) |
| { |
| this.model = model; |
| Resource resource = model.eResource(); |
| uriConverter = resource.getResourceSet().getURIConverter(); |
| this.target = computeTarget(model); |
| this.localCache = Reconciler.computeLocalCache(model); |
| } |
| |
| private URI computeTarget(Model model) |
| { |
| String target = model.getTarget(); |
| Resource resource = model.eResource(); |
| if (target == null || target.trim().isEmpty()) |
| { |
| return CommonPlugin.resolve(resource.getURI().trimSegments(0)); |
| } |
| else |
| { |
| URI targetURI = URI.createURI(target); |
| if (targetURI.isRelative()) |
| { |
| targetURI = targetURI.resolve(CommonPlugin.resolve(resource.getURI().trimSegments(0))); |
| } |
| return targetURI; |
| } |
| } |
| |
| public Model getModel() |
| { |
| return model; |
| } |
| |
| public URI getTarget() |
| { |
| return target; |
| } |
| |
| public void generate(IProgressMonitor monitor) throws IOException |
| { |
| EList<JVM> jvms = model.getJVMs(); |
| |
| SubMonitor overallMonitor = SubMonitor.convert(monitor, "Generating " + model.getName() + " to " + target, jvms.size() + 1); |
| |
| SubMonitor modelMonitor = overallMonitor.split(1); |
| modelMonitor.setWorkRemaining(9); |
| |
| modelMonitor.beginTask("Generate Model Resources " + target, 5); |
| |
| String name = model.getName(); |
| modelMonitor.subTask("Generating .gitignore"); |
| save(org.eclipse.justj.codegen.templates.GitIgnore.create(null).generate(model), target.appendSegment(".gitignore"), modelMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.POMXML.create(null).generate(model), target.appendSegment("pom.xml"), modelMonitor.split(1)); |
| |
| URI siteTarget = target.appendSegment("releng").appendSegment(name + ".site"); |
| save(org.eclipse.justj.codegen.templates.releng.site.ProjectXML.create(null).generate(model), siteTarget.appendSegment(".project"), modelMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.releng.site.CategoryXML.create(null).generate(model), siteTarget.appendSegment("category.xml"), modelMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.releng.site.POMXML.create(null).generate(model), siteTarget.appendSegment("pom.xml"), modelMonitor.split(1)); |
| |
| URI parentTarget = target.appendSegment("releng").appendSegment(name + ".parent"); |
| save(org.eclipse.justj.codegen.templates.releng.parent.ProjectXML.create(null).generate(model), parentTarget.appendSegment(".project"), modelMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.releng.parent.POMXML.create(null).generate(model), parentTarget.appendSegment("pom.xml"), modelMonitor.split(1)); |
| |
| save( |
| org.eclipse.justj.codegen.templates.releng.parent.features.POMXML.create(null).generate(model), |
| parentTarget.appendSegment("features").appendSegment("pom.xml"), |
| modelMonitor.split(1)); |
| |
| save( |
| org.eclipse.justj.codegen.templates.releng.parent.plugins.POMXML.create(null).generate(model), |
| parentTarget.appendSegment("plugins").appendSegment("pom.xml"), |
| modelMonitor.split(1)); |
| |
| String aboutURL = model.getAboutURL(); |
| String aboutHTML = composeLines(load(URI.createURI(aboutURL)), "", org.eclipse.justj.codegen.templates.GitIgnore.create(null).NL); |
| |
| for (JVM jvm : jvms) |
| { |
| SubMonitor jvmMonitor = overallMonitor.split(1); |
| |
| EList<Variant> variants = jvm.getVariants(); |
| jvmMonitor.setWorkRemaining(variants.size() + 17); |
| |
| String jvmName = jvm.getName(); |
| URI featureTarget = target.appendSegment("features").appendSegment(name + "." + jvmName + "-feature"); |
| save(org.eclipse.justj.codegen.templates.feature.ProjectXML.create(null).generate(jvm), featureTarget.appendSegment(".project"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.feature.BuildProperties.create(null).generate(jvm), featureTarget.appendSegment("build.properties"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.feature.FeatureProperties.create(null).generate(jvm), featureTarget.appendSegment("feature.properties"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.feature.FeatureXML.create(null).generate(jvm), featureTarget.appendSegment("feature.xml"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.feature.POMXML.create(null).generate(jvm), featureTarget.appendSegment("pom.xml"), jvmMonitor.split(1)); |
| |
| URI pluginTarget = target.appendSegment("plugins").appendSegment(name + "." + jvmName); |
| save(org.eclipse.justj.codegen.templates.plugin.ProjectXML.create(null).generate(jvm), pluginTarget.appendSegment(".project"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.plugin.POMXML.create(null).generate(jvm), pluginTarget.appendSegment("pom.xml"), jvmMonitor.split(1)); |
| |
| URI pluginMetaInfTarget = pluginTarget.appendSegment("META-INF"); |
| save(org.eclipse.justj.codegen.templates.plugin.Manifest.create(null).generate(jvm), pluginMetaInfTarget.appendSegment("MANIFEST.MF"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.plugin.P2Inf.create(null).generate(jvm), pluginMetaInfTarget.appendSegment("p2.inf"), jvmMonitor.split(1)); |
| |
| save(aboutHTML, pluginTarget.appendSegment("about.html"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.plugin.AboutIni.create(null).generate(jvm), pluginTarget.appendSegment("about.ini"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.plugin.AboutMappings.create(null).generate(jvm), pluginTarget.appendSegment("about.mappings"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.plugin.AboutProperties.create(null).generate(jvm), pluginTarget.appendSegment("about.properties"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.plugin.BuildProperties.create(null).generate(jvm), pluginTarget.appendSegment("build.properties"), jvmMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.plugin.PluginProperties.create(null).generate(jvm), pluginTarget.appendSegment("plugin.properties"), jvmMonitor.split(1)); |
| |
| String providerImageName = model.getProviderImageName(); |
| save(model.getProviderImageData(), pluginTarget.appendSegment(providerImageName), jvmMonitor.split(1)); |
| |
| for (Variant variant : variants) |
| { |
| SubMonitor variantMonitor = jvmMonitor.split(1); |
| variantMonitor.setWorkRemaining(10); |
| |
| String os = variant.getOs(); |
| String arch = variant.getArch(); |
| URI fragmentTarget = target.appendSegment("plugins").appendSegment(name + "." + jvmName + "." + os + "." + arch); |
| save(org.eclipse.justj.codegen.templates.fragment.ProjectXML.create(null).generate(variant), fragmentTarget.appendSegment(".project"), variantMonitor.split(1)); |
| |
| URI fragmentMetaInfTarget = fragmentTarget.appendSegment("META-INF"); |
| save(org.eclipse.justj.codegen.templates.fragment.EclipseInf.create(null).generate(variant), fragmentMetaInfTarget.appendSegment("eclipse.inf"), variantMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.fragment.Manifest.create(null).generate(variant), fragmentMetaInfTarget.appendSegment("MANIFEST.MF"), variantMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.fragment.P2Inf.create(null).generate(variant), fragmentMetaInfTarget.appendSegment("p2.inf"), variantMonitor.split(1)); |
| |
| save(aboutHTML, fragmentTarget.appendSegment("about.html"), variantMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.fragment.AboutMappings.create(null).generate(variant), fragmentTarget.appendSegment("about.mappings"), variantMonitor.split(1)); |
| save( |
| org.eclipse.justj.codegen.templates.fragment.BuildProperties.create(null).generate(variant), |
| fragmentTarget.appendSegment("build.properties"), |
| variantMonitor.split(1)); |
| save( |
| org.eclipse.justj.codegen.templates.fragment.FragmentProperties.create(null).generate(variant), |
| fragmentTarget.appendSegment("fragment.properties"), |
| variantMonitor.split(1)); |
| save(org.eclipse.justj.codegen.templates.fragment.POMXML.create(null).generate(variant), fragmentTarget.appendSegment("pom.xml"), variantMonitor.split(1)); |
| |
| URI fragmentJRETarget = fragmentTarget.appendSegment("jre"); |
| save(org.eclipse.justj.codegen.templates.fragment.GitIgnore.create(null).generate(variant), fragmentJRETarget.appendSegment(".gitignore"), variantMonitor.split(1)); |
| |
| URI fragmentSettingsTarget = fragmentTarget.appendSegment(".settings"); |
| save( |
| org.eclipse.justj.codegen.templates.fragment.PDEPrefs.create(null).generate(variant), |
| fragmentSettingsTarget.appendSegment("org.eclipse.pde.prefs"), |
| variantMonitor.split(1)); |
| |
| String source = variant.getSource(); |
| if (source != null) |
| { |
| SubMonitor untarMonitor = variantMonitor.split(1); |
| Path sourceTarGZ = CodeGenUtil.getCache(localCache, uriConverter, URI.createURI(source)); |
| untarMonitor.subTask("Untarring " + fragmentJRETarget.deresolve(target)); |
| URI jreFolder = CommonPlugin.resolve(fragmentJRETarget); |
| if (jreFolder.isFile() && jreFolder.scheme() != null) |
| { |
| Path jrePath = Paths.get(jreFolder.toFileString()); |
| CodeGenUtil.UntarToTargetHandler handler = new CodeGenUtil.UntarToTargetHandler(jrePath); |
| CodeGenUtil.untar(sourceTarGZ, handler); |
| handler.close(); |
| } |
| } |
| } |
| } |
| } |
| |
| protected void save(String text, URI target, SubMonitor monitor) throws IOException |
| { |
| monitor.subTask("Generating " + target.deresolve(this.target)); |
| try (OutputStream out = uriConverter.createOutputStream(target); PrintStream print = new PrintStream(out, true, "UTF-8")) |
| { |
| print.print(text); |
| } |
| } |
| |
| protected void save(URI source, URI target, SubMonitor monitor) throws IOException |
| { |
| monitor.subTask("Generating " + target.deresolve(this.target)); |
| try (InputStream in = uriConverter.createInputStream(source); OutputStream out = uriConverter.createOutputStream(target)) |
| { |
| byte[] buffer = new byte [10000]; |
| int length = in.read(buffer); |
| out.write(buffer, 0, length); |
| } |
| } |
| |
| protected void save(byte[] source, URI target, SubMonitor monitor) throws IOException |
| { |
| monitor.subTask("Generating " + target.deresolve(this.target)); |
| try (OutputStream out = uriConverter.createOutputStream(target); PrintStream print = new PrintStream(out, true, "UTF-8")) |
| { |
| out.write(source); |
| } |
| } |
| |
| protected String load(URI source) throws IOException |
| { |
| try (InputStream in = uriConverter.createInputStream(source)) |
| { |
| byte[] buffer = new byte [100000]; |
| int length = in.read(buffer); |
| return new String(buffer, 0, length, "UTF-8"); |
| } |
| } |
| |
| public static String getCopyright(Object argument, String prefix, String separator) |
| { |
| String copyrightText = null; |
| String copyrightYear = null; |
| String copyrightHolder = null; |
| for (Object object = argument; object instanceof Copyrightable;) |
| { |
| Copyrightable copyrightable = (Copyrightable)object; |
| if (copyrightText == null) |
| { |
| copyrightText = copyrightable.getCopyrightText(); |
| } |
| |
| if (copyrightYear == null) |
| { |
| copyrightYear = copyrightable.getCopyrightYear(); |
| } |
| |
| if (copyrightHolder == null) |
| { |
| copyrightHolder = copyrightable.getCopyrightHolder(); |
| } |
| |
| object = copyrightable.eContainer(); |
| } |
| |
| if (copyrightText != null) |
| { |
| if (copyrightHolder != null) |
| { |
| copyrightText = copyrightText.replace("${copyrightHolder}", copyrightHolder); |
| } |
| |
| if (copyrightYear != null) |
| { |
| copyrightText = copyrightText.replace("${copyrightYear}", copyrightYear); |
| } |
| |
| return composeLines(copyrightText, prefix, separator); |
| } |
| |
| return ""; |
| } |
| |
| public static Map<String, Set<String>> getTouchpoints(Object argument) |
| { |
| Map<String, Set<String>> result = new LinkedHashMap<String, Set<String>>(); |
| for (Object object = argument; object instanceof Touchable;) |
| { |
| Touchable touchable = (Touchable)object; |
| for (Touchpoint touchpoint : touchable.getTouchpoints()) |
| { |
| EList<String> instructions = touchpoint.getInstructions(); |
| if (!instructions.isEmpty()) |
| { |
| Phase phase = touchpoint.getPhase(); |
| Set<String> composedInstructions = result.get(phase.getLiteral()); |
| if (composedInstructions == null) |
| { |
| composedInstructions = new LinkedHashSet<String>(); |
| result.put(phase.getLiteral(), composedInstructions); |
| } |
| composedInstructions.addAll(instructions); |
| } |
| } |
| |
| object = touchable.eContainer(); |
| } |
| |
| return result; |
| } |
| |
| public static String composeLines(String body, String prefix, String separator) |
| { |
| if (body != null) |
| { |
| String[] lines = body.split("\r?\n", -1); |
| StringBuilder result = new StringBuilder(); |
| for (int i = 0; i < lines.length; i++) |
| { |
| String line = lines[i]; |
| result.append(prefix); |
| result.append(line); |
| if (i != lines.length - 1) |
| { |
| result.append(separator); |
| } |
| } |
| |
| return result.toString(); |
| } |
| |
| return ""; |
| } |
| |
| public static String getVersionRange(String version) |
| { |
| int[] versionValue = getVersion(version); |
| |
| return "[" + version + "," + versionValue[0] + '.' + versionValue[1] + '.' + (versionValue[2] + 1) + ")"; |
| } |
| |
| public static Map<String, Set<String>> getEECapabilities(String version) |
| { |
| int[] versionValue = getVersion(version); |
| Map<String, Set<String>> result = new LinkedHashMap<>(); |
| |
| Set<String> osgiMinimum = new LinkedHashSet<>(); |
| result.put("OSGi/Minimum", osgiMinimum); |
| for (int i = 0; i <= 2; ++i) |
| { |
| osgiMinimum.add("1." + i); |
| } |
| |
| Set<String> jre = new LinkedHashSet<>(); |
| result.put("JRE", jre); |
| for (int i = 0; i <= 1; ++i) |
| { |
| jre.add("1." + i); |
| } |
| |
| Set<String> javaSE = new LinkedHashSet<>(); |
| result.put("JavaSE", javaSE); |
| for (int i = 0; i <= 8; ++i) |
| { |
| javaSE.add("1." + i); |
| } |
| for (int i = 9; i <= versionValue[0]; ++i) |
| { |
| javaSE.add("" + i + ".0"); |
| } |
| |
| for (int compact = 1; compact <= 3; ++compact) |
| { |
| Set<String> javaCompact = new LinkedHashSet<>(); |
| result.put("JavaSE/compact" + compact, javaCompact); |
| javaCompact.add("1.8"); |
| for (int i = 9; i <= versionValue[0]; ++i) |
| { |
| javaCompact.add("" + i + ".0"); |
| } |
| } |
| |
| return result; |
| } |
| |
| public static class Application implements IApplication |
| { |
| @Override |
| public Object start(IApplicationContext context) throws Exception |
| { |
| System.out.println("start"); |
| main((String[])context.getArguments().get("application.args")); |
| return null; |
| } |
| |
| @Override |
| public void stop() |
| { |
| } |
| } |
| |
| private static Pattern VERSION_PATTERN = Pattern.compile("([0-9]+)\\.([0-9]+)\\.([0-9]+)"); |
| |
| private static int[] getVersion(String version) |
| { |
| Matcher matcher = VERSION_PATTERN.matcher(version); |
| if (!matcher.matches()) |
| { |
| throw new IllegalArgumentException("Invalid version " + version); |
| } |
| |
| return new int []{ Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3)) }; |
| } |
| } |