blob: c7d543c46509b90a978ffc5d0b534ec08288585d [file] [log] [blame]
/**
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. 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
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*
*
* This copyright notice shows up in the generated Java code
*/
package org.eclipse.osbp.xtext.topologydsl.jvmmodel;
import com.ejt.vaadin.sizereporter.ComponentResizeEvent;
import com.ejt.vaadin.sizereporter.ComponentResizeListener;
import com.ejt.vaadin.sizereporter.SizeReporter;
import com.google.common.base.Objects;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.JavaScriptFunction;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import elemental.json.JsonArray;
import elemental.json.JsonException;
import elemental.json.impl.JreJsonString;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.commons.io.IOUtils;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl;
import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent;
import org.eclipse.osbp.ui.api.e4.IE4Focusable;
import org.eclipse.osbp.xtext.basic.generator.BasicDslGeneratorUtils;
import org.eclipse.osbp.xtext.i18n.I18NModelGenerator;
import org.eclipse.osbp.xtext.topologydsl.Topology;
import org.eclipse.osbp.xtext.topologydsl.TopologyModel;
import org.eclipse.osbp.xtext.topologydsl.TopologyPackage;
import org.eclipse.osbp.xtext.topologydsl.TopologyProjection;
import org.eclipse.osbp.xtext.topologydsl.jvmmodel.D3JsJavaUtil;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.xbase.compiler.GeneratorConfig;
import org.eclipse.xtext.xbase.compiler.ImportManager;
import org.eclipse.xtext.xbase.compiler.output.TreeAppendable;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.StringExtensions;
@SuppressWarnings("all")
public class TopologyModelGenerator extends I18NModelGenerator {
@Inject
@Extension
private IQualifiedNameProvider _iQualifiedNameProvider;
@Inject
@Extension
private D3JsJavaUtil _d3JsJavaUtil;
@Inject
@Extension
private BasicDslGeneratorUtils _basicDslGeneratorUtils;
@Override
public TreeAppendable createAppendable(final EObject context, final ImportManager importManager, final GeneratorConfig config) {
TreeAppendable _xblockexpression = null;
{
this.setBuilder(context.eResource());
this._basicDslGeneratorUtils.addImportFor(this, importManager, this._typeReferenceBuilder, Label.class, List.class, ArrayList.class, HorizontalLayout.class, Notification.class, IEventBroker.class, JavaScriptFunction.class, JsonArray.class, JsonException.class, JreJsonString.class, InputStream.class, IOUtils.class, IOException.class, Notification.class, Adapter.class, AdapterImpl.class, EObject.class, UIElementImpl.class, UiPackageImpl.class, SizeReporter.class, ComponentResizeListener.class, ComponentResizeEvent.class, EventDispatcherEvent.class, EventDispatcherEvent.EventDispatcherDataTag.class, EventDispatcherEvent.EventDispatcherCommand.class, IE4Focusable.class, Panel.class);
_xblockexpression = super.createAppendable(context, importManager, config);
}
return _xblockexpression;
}
@Override
public void doGenerate(final Resource input, final IFileSystemAccess fsa) {
super.doGenerate(input, fsa);
EList<EObject> _contents = input.getContents();
for (final EObject obj : _contents) {
if ((obj instanceof TopologyModel)) {
this.jsGenerate(((TopologyModel) obj), fsa);
}
}
}
public void jsGenerate(final TopologyModel topologyModel, final IFileSystemAccess fsa) {
EList<TopologyPackage> _packages = topologyModel.getPackages();
for (final TopologyPackage pkg : _packages) {
EList<Topology> _topologies = pkg.getTopologies();
for (final Topology topology : _topologies) {
{
String pckgName = this._iQualifiedNameProvider.getFullyQualifiedName(pkg).toString();
StringBuilder strBuilder = new StringBuilder();
String pckgNamePath = pckgName.replaceAll("\\.", "/");
StringConcatenation _builder = new StringConcatenation();
_builder.append(pckgNamePath);
_builder.append("/js/");
String _createTopologyJsFilename = this._d3JsJavaUtil.createTopologyJsFilename(topology);
_builder.append(_createTopologyJsFilename);
String propOutputFile = _builder.toString();
this.generateJsFile(topology, strBuilder);
int _length = strBuilder.length();
boolean _greaterThan = (_length > 0);
if (_greaterThan) {
fsa.generateFile(propOutputFile, strBuilder);
}
}
}
}
}
public void generateJsFile(final Topology topology, final StringBuilder strBuilder) {
String topologyFilePath = this._d3JsJavaUtil.createfullyQualifiedTopologyFilename(topology).replaceAll("\\.", "_");
this.generateTopoJsFile(strBuilder, topologyFilePath, topology);
}
public StringBuilder generateTopoJsFile(final StringBuilder strBuilder, final String topologyJavaFileName, final Topology topology) {
StringConcatenation _builder = new StringConcatenation();
_builder.append(topologyJavaFileName);
_builder.append(" = function() {");
_builder.newLineIfNotEmpty();
_builder.append("\t");
_builder.append("var connector = this;");
_builder.newLine();
_builder.append("\t");
_builder.append("var width = this.getState().panelWidth;");
_builder.newLine();
_builder.append("\t");
_builder.append("var height = this.getState().panelHeight;");
_builder.newLine();
_builder.append(" ");
_builder.append("var scale = 2*(width < height)?width:height;");
_builder.newLine();
_builder.append(" ");
_builder.append("scale = scale>1000?1000:scale;");
_builder.newLine();
_builder.append("\t");
String countryNameUpper = topology.getFileName();
_builder.newLineIfNotEmpty();
_builder.append("\t");
String countryName = topology.getFileName();
_builder.newLineIfNotEmpty();
_builder.append("\t");
CharSequence _generateProjection = this.generateProjection(topology);
_builder.append(_generateProjection, "\t");
_builder.newLineIfNotEmpty();
_builder.append("\t");
_builder.newLine();
_builder.append("\t");
_builder.append("var path = d3.geoPath().projection(projection);");
_builder.newLine();
_builder.append("\t");
_builder.newLine();
_builder.append("\t");
_builder.append("var cxD3");
_builder.append(countryNameUpper, "\t");
_builder.append("TopoJsHTMLRootComponent = this.getElement();");
_builder.newLineIfNotEmpty();
_builder.append("\t");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t");
_builder.append("TopoJsHTMLRootComponent.innerHTML = \t");
_builder.newLineIfNotEmpty();
_builder.append("\t\t\t\t\t");
_builder.append("\"<div id=\\\"\"+this.getState().htmlTagId+\"_div\\\">\" + \"</div>\";\t");
_builder.newLine();
_builder.append("\t");
_builder.newLine();
_builder.append("\t");
_builder.append("var cxD3");
_builder.append(countryNameUpper, "\t");
_builder.append("TopoJsHTMLRootComponentSelection = d3.select(cxD3");
_builder.append(countryNameUpper, "\t");
_builder.append("TopoJsHTMLRootComponent).select(\"#\"+this.getState().htmlTagId+\"_div\");");
_builder.newLineIfNotEmpty();
_builder.append("\t");
_builder.newLine();
_builder.append("\t");
_builder.append("var cxD3");
_builder.append(countryNameUpper, "\t");
_builder.append("TopoJsHTMLRootComponentSvg = cxD3");
_builder.append(countryNameUpper, "\t");
_builder.append("TopoJsHTMLRootComponentSelection.append(\"svg\")");
_builder.newLineIfNotEmpty();
_builder.append("\t ");
_builder.append(".attr(\"width\", width)");
_builder.newLine();
_builder.append("\t ");
_builder.append(".attr(\"height\", height);");
_builder.newLine();
_builder.newLine();
_builder.append("\t");
_builder.append("var cxD3");
_builder.append(countryNameUpper, "\t");
_builder.append("TopoJsHTMLRootComponentG = cxD3");
_builder.append(countryNameUpper, "\t");
_builder.append("TopoJsHTMLRootComponentSvg.append(\"g\");");
_builder.newLineIfNotEmpty();
_builder.append("\t");
_builder.newLine();
{
boolean _isZoomable = topology.isZoomable();
if (_isZoomable) {
_builder.append("\t");
_builder.append("var zoom = d3.zoom()");
_builder.newLine();
_builder.append("\t");
_builder.append(" ");
_builder.append(".scaleExtent([1, 8])");
_builder.newLine();
_builder.append("\t");
_builder.append(" ");
_builder.append(".on(\"zoom\",function() {");
_builder.newLine();
_builder.append("\t");
_builder.append(" ");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t ");
_builder.append("TopoJsHTMLRootComponentG.attr(\"transform\",\"translate(\"+ ");
_builder.newLineIfNotEmpty();
_builder.append("\t");
_builder.append(" \t");
_builder.append("d3.event.translate +\")scale(\" + d3.event.scale + \")\");");
_builder.newLine();
_builder.append("\t");
_builder.append("\t");
_builder.append("});");
_builder.newLine();
}
}
_builder.append("\t");
_builder.newLine();
_builder.append("\t");
_builder.append("jsonTreeFunction = function(topology) {");
_builder.newLine();
_builder.append("\t\t");
String topologyObject = "unit";
_builder.newLineIfNotEmpty();
{
TopologyProjection _projection = topology.getProjection();
boolean _equals = Objects.equal(_projection, TopologyProjection.WORLD);
boolean _not = (!_equals);
if (_not) {
_builder.append("\t\t");
_builder.append("// To create the \'unit\'");
_builder.newLine();
_builder.append("\t\t");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t\t");
_builder.append("TopoJsHTMLRootComponentG.selectAll(\".unit\")");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("\t");
_builder.append(".data(topojson.feature(topology, topology.objects.");
_builder.append(topologyObject, "\t\t\t");
_builder.append(").features)");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("\t");
_builder.append(".enter().append(\"path\")");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append(".attr(\"class\", function(d) { return \"");
_builder.append(countryName, "\t\t\t");
_builder.append(" unit \" + d.id; })");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("\t");
_builder.append(".attr(\"d\", path);");
_builder.newLine();
_builder.append("\t\t");
_builder.append("// To create the \'");
_builder.append(topologyObject = "states", "\t\t");
_builder.append(" of a country\'");
_builder.newLineIfNotEmpty();
} else {
_builder.append("\t\t");
_builder.append("// To create the countries of the \'");
_builder.append(topologyObject = "world", "\t\t");
_builder.append("\'");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("\t");
topology.setPartition(true);
_builder.newLineIfNotEmpty();
}
}
{
boolean _isPartition = topology.isPartition();
if (_isPartition) {
_builder.append("\t\t");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t\t");
_builder.append("TopoJsHTMLRootComponentG.selectAll(\"path\")");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append(".data(topojson.feature(topology, topology.objects.");
_builder.append(topologyObject, "\t\t");
_builder.append(").features)");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append(".enter().append(\"path\")");
_builder.newLine();
_builder.append("\t\t");
_builder.append(".attr(\"class\", \"");
_builder.append(countryName, "\t\t");
_builder.append("\")");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append(".attr(\"d\", path);");
_builder.newLine();
_builder.append("\t\t");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t\t");
_builder.append("TopoJsHTMLRootComponentG.selectAll(\"path\").on(\"click\", function click(d) {");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("\t");
_builder.append("var data = this.__data__;");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append("var id = data.id;");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append("if (data.properties.iso_3166_2 != null)\t{");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t\t");
_builder.append("id = data.properties.iso_3166_2;");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append("}");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append("var name = data.properties.");
String _literal = topology.getProperty().getLiteral();
_builder.append(_literal, "\t\t\t");
_builder.append(";");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("\t");
_builder.append("connector.on");
String _fileName = topology.getFileName();
_builder.append(_fileName, "\t\t\t");
_builder.append("Click(id, name);");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("});");
_builder.newLine();
}
}
_builder.append("\t \t\t\t");
_builder.newLine();
{
boolean _isPlaces = topology.isPlaces();
if (_isPlaces) {
_builder.append("\t\t");
_builder.append("// To create the cities");
_builder.newLine();
_builder.append("\t\t");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t\t");
_builder.append("TopoJsHTMLRootComponentG.selectAll(\".place-label\")");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("\t");
_builder.append(".data(topojson.feature(topology, topology.objects.places).features)");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append(".enter().append(\"text\")");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append(".attr(\"class\", \"place-label\")");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append(".attr(\"transform\", function(d) { ");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t\t");
_builder.append("return \"translate(\" + projection(d.geometry.coordinates)+\")\";})");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t\t");
_builder.append(".attr(\"dy\", \".35em\")");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t\t");
_builder.append(".text(function(d) { return d.properties.name;");
_builder.newLine();
_builder.append("\t\t");
_builder.append("}); ");
_builder.newLine();
_builder.append("\t\t");
_builder.append("// To create the city dots");
_builder.newLine();
_builder.append("\t\t");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t\t");
_builder.append("TopoJsHTMLRootComponentG.append(\"path\")");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append(" ");
_builder.append(".datum(topojson.feature(topology, topology.objects.places))");
_builder.newLine();
_builder.append("\t\t");
_builder.append(" ");
_builder.append(".attr(\"d\", path)");
_builder.newLine();
_builder.append("\t\t");
_builder.append(" ");
_builder.append(".attr(\"class\", \"place\");");
_builder.newLine();
_builder.append("\t\t");
_builder.append("// sends the city labels to Server");
_builder.newLine();
_builder.append("\t\t");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t\t");
_builder.append("TopoJsHTMLRootComponentG.selectAll(\"text.place-label\").on(\"click\", function click(d) {");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append(" \t");
_builder.append("var data = this.__data__;");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append("var id = data.id;");
_builder.newLine();
_builder.append("\t\t");
_builder.append("\t");
_builder.append("var name = data.properties.");
String _literal_1 = topology.getProperty().getLiteral();
_builder.append(_literal_1, "\t\t\t");
_builder.append(";");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append(" \t");
_builder.append("connector.on");
String _fileName_1 = topology.getFileName();
_builder.append(_fileName_1, "\t\t \t");
_builder.append("Click(id, name);");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append("});");
_builder.newLine();
}
}
_builder.append("\t\t");
_builder.newLine();
{
boolean _isZoomable_1 = topology.isZoomable();
if (_isZoomable_1) {
_builder.append("\t\t");
_builder.append("cxD3");
_builder.append(countryNameUpper, "\t\t");
_builder.append("TopoJsHTMLRootComponentSvg.call(zoom).call(zoom.event);");
_builder.newLineIfNotEmpty();
}
}
_builder.append("\t");
_builder.append("};");
_builder.newLine();
_builder.append("\t");
_builder.append("jsonTreeFunction(JSON.parse(this.getState().jsonData));");
_builder.newLine();
_builder.append("}");
_builder.newLine();
return strBuilder.append(_builder);
}
public CharSequence generateProjection(final Topology topology) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("var projection = d3.geo");
String _firstUpper = StringExtensions.toFirstUpper(topology.getProjection().getLiteral());
_builder.append(_firstUpper);
_builder.append("()");
_builder.newLineIfNotEmpty();
_builder.append(" \t\t\t\t\t");
{
boolean _isHasRotation = topology.isHasRotation();
if (_isHasRotation) {
_builder.append(".rotate([");
int _rotate_x = topology.getRotate_x();
_builder.append(_rotate_x, " \t\t\t\t\t");
_builder.append(", ");
int _rotate_y = topology.getRotate_y();
_builder.append(_rotate_y, " \t\t\t\t\t");
_builder.append("])");
}
}
_builder.newLineIfNotEmpty();
_builder.append(" \t\t\t\t\t");
{
boolean _isHasCentering = topology.isHasCentering();
if (_isHasCentering) {
_builder.append(".center([");
int _center_x = topology.getCenter_x();
_builder.append(_center_x, " \t\t\t\t\t");
_builder.append(", ");
int _center_y = topology.getCenter_y();
_builder.append(_center_y, " \t\t\t\t\t");
_builder.append("])");
}
}
_builder.newLineIfNotEmpty();
_builder.append(" \t\t\t\t\t");
{
boolean _isHasScaling = topology.isHasScaling();
if (_isHasScaling) {
_builder.append(".scale(scale*");
double _scale = topology.getScale();
_builder.append(_scale, " \t\t\t\t\t");
_builder.append(")");
} else {
_builder.append(".scale(scale)");
}
}
_builder.append(" ");
_builder.newLineIfNotEmpty();
_builder.append("\t\t\t\t\t");
{
boolean _isHasTranslation = topology.isHasTranslation();
if (_isHasTranslation) {
_builder.append(".translate([");
int _translate_x = topology.getTranslate_x();
_builder.append(_translate_x, "\t\t\t\t\t");
_builder.append(", ");
int _translate_y = topology.getTranslate_y();
_builder.append(_translate_y, "\t\t\t\t\t");
_builder.append("])");
} else {
_builder.append(".translate([width / 2, height / 2])");
}
}
_builder.append(";");
_builder.newLineIfNotEmpty();
return _builder;
}
}