Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Mollik2017-08-28 15:40:12 +0000
committerRalf Mollik2017-08-28 15:40:12 +0000
commit5242629acf3fa3f994ef12e40e21006ecf2d4114 (patch)
tree57f3a4a0466bc6f10608df82f839592ffcec7c81 /org.eclipse.osbp.xtext.datainterchange/src/org/eclipse
downloadorg.eclipse.osbp.xtext.datainterchange-5242629acf3fa3f994ef12e40e21006ecf2d4114.tar.gz
org.eclipse.osbp.xtext.datainterchange-5242629acf3fa3f994ef12e40e21006ecf2d4114.tar.xz
org.eclipse.osbp.xtext.datainterchange-5242629acf3fa3f994ef12e40e21006ecf2d4114.zip
parallel ip - initial checkin
Signed-off-by: Ralf Mollik <ramollik@compex-commerce.com>
Diffstat (limited to 'org.eclipse.osbp.xtext.datainterchange/src/org/eclipse')
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/Activator.java47
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSL.xtext142
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLBundleSpaceRuntimeModule.java42
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLBundleSpaceStandaloneSetup.java40
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLRuntimeModule.java77
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLStandaloneSetup.java26
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/GenerateDataDSL.mwe2164
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/XcoreResourceFactory.java28
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/formatting/DataDSLFormatter.xtend46
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/jvmmodel/DataDSLJvmModelInferrer.xtend1055
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/jvmmodel/DataDSLModelGenerator.xtend1060
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/scoping/DataDSLScopeProvider.xtend233
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/validation/DataDSLValidator.xtend38
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/valueconverter/DataDSLQualifiedNameProvider.java36
-rw-r--r--org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/valueconverter/DataDSLValueConverterService.java41
15 files changed, 3075 insertions, 0 deletions
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/Activator.java b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/Activator.java
new file mode 100644
index 0000000..9e91749
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/Activator.java
@@ -0,0 +1,47 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+ package org.eclipse.osbp.xtext.datainterchange;
+
+
+import org.eclipse.osbp.gitinfo.Loginfo;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext context;
+
+ static BundleContext getContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ Activator.context = bundleContext;
+ Loginfo li = new Loginfo();
+ li.print( Activator.class.getCanonicalName(), Activator.class.getClassLoader());
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ Activator.context = null;
+ }
+
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSL.xtext b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSL.xtext
new file mode 100644
index 0000000..16f1808
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSL.xtext
@@ -0,0 +1,142 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+
+grammar org.eclipse.osbp.xtext.datainterchange.DataDSL with org.eclipse.xtext.xbase.annotations.XbaseWithAnnotations
+
+import "http://osbp.eclipse.org/xtext/datainterchange/DataDSL"
+
+import "http://osbp.eclipse.org/dsl/common/types/v1" as types
+import "http://osbp.eclipse.org/dsl/entity/v1" as entity
+import "http://www.eclipse.org/emf/2002/Ecore" as ecore
+
+DataInterchangeModel:
+ packages+=DataInterchangePackage*;
+
+DataInterchangePackage:
+ {DataInterchangePackage} 'package' name=QualifiedName 'title' title=TRANSLATABLESTRING
+ ('{' (imports+=DataInterchangeImport)* (datInts+=DataInterchange)* '}' )?;
+
+DataInterchange:
+ {DataInterchange} 'interchange' name=TRANSLATABLEID
+ (description?='described by' descriptionValue=TRANSLATABLESTRING)?
+ (createReport?='create report')?
+ ('averageElementSize' elementSize=INT)?
+ ('progressBarStyle' progressBarStyle=ProgressBarStylesEnum)?
+ (refreshEnabled?='refreshViewWhenFinished' refresh=STRING)?
+ 'file' fileEndpoint=DataInterchangeFile 'beans' '{' (path+=DataInterchangeBean)* '}';
+
+DataInterchangeFile:
+ DataInterchangeFileXML | DataInterchangeFileCSV | DataInterchangeFileEDI;
+
+DataInterchangeFileXML:
+ {DataInterchangeFileXML} 'XML' fileURL=STRING;
+
+DataInterchangeFileCSV:
+ {DataInterchangeFileCSV} 'CSV' fileURL=STRING
+ (
+ ('delimiter' delimiter=STRING)? & ('quoteCharacter' quoteCharacter=STRING)? & ('skipLines' skipLines=INT)? &
+ (indent?='indent')? & (strict?='strict')? & (validateHeader?='validateHeader')? & ('encoding' encoding=STRING)?
+ );
+
+DataInterchangeFileEDI:
+ {DataInterchangeFileEDI} 'EDI' fileURL=STRING 'mappingModel' mappingModel=STRING (validate?='validate')?;
+
+DataInterchangeBean:
+ {DataInterchangeBean}
+ 'entity' entity=[entity::LEntity|LFQN]
+ ('createOn' elementMap=STRING)?
+ (markLatest?='marker' latestProperty=[entity::LEntityAttribute])?
+ ((recordElement?='recordElement') |
+ (recordList?='recordList'))?
+ ('expression' '{' (expression+=DataInterchangeExpression)* '}')?
+ ('lookup' '{' (lookup+=DataInterchangeLookup)* '}')?
+ ('format' '{' (format+=DataInterchangeFormat)* '}')?
+ ('mapping' '{' (mappings+=DataInterchangeMapping)* '}')?
+ ;
+
+DataInterchangeLookup:
+ {DataInterchangeLookup}
+ 'for' targetProperty=[entity::LEntityReference]
+ 'on' entity=[entity::LEntity]
+ ('createOn' elementMap=STRING)?
+ 'with' queryProperty=[entity::LEntityAttribute]
+ (cached?='cacheSize' cacheSize=INT)?
+ ('mapTo' dataMap=STRING)?
+ (
+ (allowNoResult?='allowNoResult')? &
+ (allowNonuniqueResult?='allowNonuniqueResult')? &
+ (markerPath=DataInterchangeMarkerPath)?
+ );
+
+DataInterchangeMarkerPath:
+ {DataInterchangeMarkerPath}
+ 'markerPath' '{' (path+=DataInterchangeMarkerEntity)* '}';
+
+DataInterchangeMarkerEntity:
+ {DataInterchangeMarkerEntity}
+ 'markerEntity' markerEntity=[entity::LEntity|LFQN]
+ (markLatest?='markedBy' markerProperty=[entity::LEntityAttribute])?;
+
+DataInterchangeFormat:
+ {DataInterchangeFormat} 'for' targetProperty=[entity::LEntityAttribute] 'coding' format=STRING ('locale' locale=STRING)?;
+
+DataInterchangeExpression:
+ DataInterchangeEntityExpression | DataInterchangePredefinedExpression;
+
+DataInterchangeEntityExpression:
+ {DataInterchangeEntityExpression} 'copy' targetProperty=[entity::LEntityAttribute] 'from' entity=[entity::LEntity|LFQN] 'property' property=[entity::LEntityAttribute];
+
+DataInterchangePredefinedExpression:
+ {DataInterchangePredefinedExpression} 'assign' targetProperty=[entity::LEntityAttribute] 'with' bean=PredefinedBeanEnum 'as' beanType=PredefinedBeanTypeEnum;
+
+DataInterchangeMapping:
+ {DataInterchangeMapping} 'map' property=[entity::LEntityAttribute] 'to' data=STRING;
+
+DataInterchangeImport returns types::LImport:
+'import' importedNamespace=DataInterchangeQualifiedNameWithWildCard;
+
+DataInterchangeQualifiedNameWithWildCard:
+ QualifiedName ('.' '*')?;
+
+QualifiedName:
+ ValidID (=>'.' ValidID)*;
+
+ValidID:
+ ID;
+
+LFQN:
+ ID ('.' ID)*;
+
+TRANSLATABLESTRING:
+ STRING;
+
+TRANSLATABLEID:
+ ID;
+
+enum PredefinedBeanEnum:
+ now = 'NowDate'|
+ start = 'StartDate'|
+ UUID = 'UniversallyUniqueIdentifier';
+
+enum PredefinedBeanTypeEnum:
+ Date = 'Date'|
+ Millis = 'Milliseconds'|
+ Nanos = 'Nanoseconds'|
+ random = 'Random'|
+ execContext = 'ExecuteContext';
+
+enum ProgressBarStylesEnum:
+ none = 'none'|
+ normal = 'normal'|
+ important = 'important';
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLBundleSpaceRuntimeModule.java b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLBundleSpaceRuntimeModule.java
new file mode 100644
index 0000000..4efabf9
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLBundleSpaceRuntimeModule.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+ package org.eclipse.osbp.xtext.datainterchange;
+
+import org.eclipse.osbp.dsl.xtext.types.bundles.BundleSpaceTypeProviderFactory;
+import org.eclipse.osbp.dsl.xtext.types.bundles.BundleSpaceTypeScopeProvider;
+import org.eclipse.osbp.xtext.builder.types.loader.api.ITypeLoaderFactory;
+import org.eclipse.osbp.xtext.builder.types.loader.api.ITypeLoaderProvider;
+import org.eclipse.osbp.xtext.builder.types.loader.runtime.TypeLoaderFactory;
+import org.eclipse.osbp.xtext.builder.types.loader.runtime.TypeLoaderProvider;
+
+@SuppressWarnings("restriction")
+public class DataDSLBundleSpaceRuntimeModule extends DataDSLRuntimeModule {
+ // contributed by org.eclipse.xtext.generator.types.TypesGeneratorFragment
+ public Class<? extends org.eclipse.xtext.common.types.access.IJvmTypeProvider.Factory> bindIJvmTypeProvider$Factory() {
+ return BundleSpaceTypeProviderFactory.class;
+ }
+
+ // contributed by org.eclipse.xtext.generator.types.TypesGeneratorFragment
+ public Class<? extends org.eclipse.xtext.common.types.xtext.AbstractTypeScopeProvider> bindAbstractTypeScopeProvider() {
+ return BundleSpaceTypeScopeProvider.class;
+ }
+
+ public Class<? extends ITypeLoaderFactory> bindITypeLoaderFactory() {
+ return TypeLoaderFactory.class;
+ }
+
+ public Class<? extends ITypeLoaderProvider> ITypeLoaderProvider() {
+ return TypeLoaderProvider.class;
+ }
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLBundleSpaceStandaloneSetup.java b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLBundleSpaceStandaloneSetup.java
new file mode 100644
index 0000000..0908fa6
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLBundleSpaceStandaloneSetup.java
@@ -0,0 +1,40 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+ package org.eclipse.osbp.xtext.datainterchange;
+
+import org.eclipse.osbp.xtext.builder.xbase.setups.XbaseBundleSpaceStandaloneSetup;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+@SuppressWarnings("restriction")
+public class DataDSLBundleSpaceStandaloneSetup extends DataDSLStandaloneSetup {
+ public static void doSetup() {
+ new DataDSLBundleSpaceStandaloneSetup().createInjectorAndDoEMFRegistration();
+ }
+
+ @Override
+ public Injector createInjectorAndDoEMFRegistration() {
+ XbaseBundleSpaceStandaloneSetup.doSetup();
+
+ Injector injector = createInjector();
+ register(injector);
+ return injector;
+ }
+
+ @Override
+ public Injector createInjector() {
+ return Guice.createInjector(new DataDSLBundleSpaceRuntimeModule());
+ }
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLRuntimeModule.java b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLRuntimeModule.java
new file mode 100644
index 0000000..461b754
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLRuntimeModule.java
@@ -0,0 +1,77 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+ package org.eclipse.osbp.xtext.datainterchange;
+
+import javax.inject.Singleton;
+
+import org.eclipse.xtext.conversion.IValueConverterService;
+import org.eclipse.xtext.generator.IGenerator;
+import org.eclipse.xtext.generator.IOutputConfigurationProvider;
+import org.eclipse.xtext.naming.IQualifiedNameProvider;
+import org.eclipse.xtext.scoping.IScopeProvider;
+import org.eclipse.osbp.dsl.xtext.lazyresolver.LazyJvmTypeLinker;
+import org.eclipse.osbp.dsl.xtext.lazyresolver.SemanticLoadingResource;
+import org.eclipse.osbp.dsl.xtext.lazyresolver.linker.LazyJvmTypeTransientValueService;
+
+import com.google.inject.Binder;
+
+import org.eclipse.osbp.xtext.datainterchange.jvmmodel.DataDSLModelGenerator;
+import org.eclipse.osbp.xtext.datainterchange.scoping.DataDSLScopeProvider;
+import org.eclipse.osbp.xtext.datainterchange.valueconverter.DataDSLQualifiedNameProvider;
+import org.eclipse.osbp.xtext.datainterchange.valueconverter.DataDSLValueConverterService;
+import org.eclipse.osbp.xtext.i18n.DSLOutputConfigurationProvider;
+
+/**
+ * Use this class to register components to be used at runtime / without the Equinox extension registry.
+ */
+public class DataDSLRuntimeModule extends org.eclipse.osbp.xtext.datainterchange.AbstractDataDSLRuntimeModule {
+ @Override
+ public Class<? extends IGenerator> bindIGenerator() {
+ return DataDSLModelGenerator.class;
+ }
+
+ @Override
+ public Class<? extends IScopeProvider> bindIScopeProvider() {
+ return DataDSLScopeProvider.class;
+ }
+
+ @Override
+ public Class<? extends IQualifiedNameProvider> bindIQualifiedNameProvider() {
+ return DataDSLQualifiedNameProvider.class;
+ }
+
+ @Override
+ public Class<? extends IValueConverterService> bindIValueConverterService() {
+ return DataDSLValueConverterService.class;
+ }
+
+ @Override
+ public void configure(Binder binder) {
+ super.configure(binder);
+ binder.bind(IOutputConfigurationProvider.class).to(DSLOutputConfigurationProvider.class).in(Singleton.class);
+ }
+
+ public Class<? extends org.eclipse.xtext.resource.XtextResource> bindXtextResource() {
+ return SemanticLoadingResource.class;
+ }
+
+ public Class<? extends org.eclipse.xtext.linking.ILinker> bindILinker() {
+ return LazyJvmTypeLinker.class;
+ }
+
+ public Class<? extends org.eclipse.xtext.serializer.sequencer.ITransientValueService> bindSerializerITransientValueService() {
+ return LazyJvmTypeTransientValueService.class;
+ }
+
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLStandaloneSetup.java b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLStandaloneSetup.java
new file mode 100644
index 0000000..385a19b
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/DataDSLStandaloneSetup.java
@@ -0,0 +1,26 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+ package org.eclipse.osbp.xtext.datainterchange;
+
+/**
+ * Initialization support for running Xtext languages
+ * without equinox extension registry
+ */
+public class DataDSLStandaloneSetup extends DataDSLStandaloneSetupGenerated{
+
+ public static void doSetup() {
+ new DataDSLStandaloneSetup().createInjectorAndDoEMFRegistration();
+ }
+}
+
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/GenerateDataDSL.mwe2 b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/GenerateDataDSL.mwe2
new file mode 100644
index 0000000..1b9f021
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/GenerateDataDSL.mwe2
@@ -0,0 +1,164 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+module org.eclipse.osbp.xtext.datainterchange.GenerateDataDSL
+
+import org.eclipse.emf.mwe.utils.*
+import org.eclipse.xtext.generator.*
+import org.eclipse.xtext.ui.generator.*
+import org.eclipse.osbp.dsl.mwe.*
+
+var projectName = "org.eclipse.osbp.xtext.datainterchange"
+var grammarURI = "platform:/resource/${projectName}/src/org/eclipse/osbp/xtext/datainterchange/DataDSL.xtext"
+var fileExtensions = "data"
+var runtimeProject = "../${projectName}"
+var generateXtendStub = true
+var encoding = "UTF-8"
+
+Workflow {
+ bean = org.eclipse.emf.ecore.xcore.XcoreStandaloneSetup : xcore {}
+ bean = org.eclipse.xtext.mwe.Reader {
+ register = xcore
+ }
+ bean = MavenStandaloneSetup {
+ scanClassPath = true
+ platformUri = "${runtimeProject}/.."
+ registerGenModelFile = "platform:/resource/org.eclipse.osbp.xtext.datainterchange/model/DataDSL.xcore"
+// registerEcoreFile = "platform:/resource/org.eclipse.osbp.xtext.datainterchange/model/DataDSL.xcore"
+ registerGeneratedEPackage = "org.eclipse.osbp.xtext.datainterchange.DataDSLPackage"
+
+ registerGenModelFile = "platform:/resource/org.eclipse.osbp.dsl.entity.xtext/model/entity.xcore"
+// registerEcoreFile = "platform:/resource/org.eclipse.osbp.dsl.entity.xtext/model/entity.xcore"
+
+ registerGenModelFile = "platform:/resource/org.eclipse.osbp.dsl.common.xtext/model/types.xcore"
+// registerEcoreFile = "platform:/resource/org.eclipse.osbp.dsl.common.xtext/model/types.xcore"
+
+ registerGenModelFile = "platform:/resource/org.eclipse.xtext.common.types/model/JavaVMTypes.genmodel"
+ registerEcoreFile = "platform:/resource/org.eclipse.xtext.common.types/model/JavaVMTypes.ecore"
+
+ registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
+ registerEcoreFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xtype.ecore"
+ registerEcoreFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.ecore"
+ registerEcoreFile = "platform:/resource/org.eclipse.xtext.xbase/model/XAnnotations.ecore"
+ }
+
+ component = DirectoryCleaner {
+ directory = "${runtimeProject}/src-gen"
+ exclude = "README.txt"
+ }
+
+ component = DirectoryCleaner {
+ directory = "${runtimeProject}.ui/src-gen"
+ exclude = "README.txt"
+ }
+
+ component = DirectoryCleaner {
+ directory = "${runtimeProject}.tests/src-gen"
+ exclude = "README.txt"
+ }
+
+ component = Generator {
+ pathRtProject = runtimeProject
+ pathUiProject = "${runtimeProject}.ui"
+ pathTestProject = "${runtimeProject}.tests"
+ projectNameRt = projectName
+ projectNameUi = "${projectName}.ui"
+ encoding = encoding
+ language = auto-inject {
+ uri = grammarURI
+
+ // Java API to access grammar elements (required by several other fragments)
+ fragment = grammarAccess.GrammarAccessFragment auto-inject {}
+
+ // generates Java API for the generated EPackages
+ fragment = ecore.EMFGeneratorFragment auto-inject {}
+
+ // the old serialization component
+ // fragment = parseTreeConstructor.ParseTreeConstructorFragment auto-inject {}
+
+ // serializer 2.0
+ fragment = serializer.SerializerFragment auto-inject {
+ generateStub = false
+ }
+
+ // a custom ResourceFactory for use with EMF
+ fragment = resourceFactory.ResourceFactoryFragment auto-inject {}
+
+ // The antlr parser generator fragment.
+ fragment = parser.antlr.XtextAntlrGeneratorFragment auto-inject {
+ // options = {
+ // backtrack = true
+ // }
+ }
+
+ // Xtend-based API for validation
+ fragment = validation.ValidatorFragment auto-inject {
+ // composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
+ // composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
+ }
+
+ // old scoping and exporting API
+ // fragment = scoping.ImportURIScopingFragment auto-inject {}
+ // fragment = exporting.SimpleNamesFragment auto-inject {}
+
+ // scoping and exporting API
+ fragment = scoping.ImportNamespacesScopingFragment auto-inject {}
+ fragment = exporting.QualifiedNamesFragment auto-inject {}
+ fragment = builder.BuilderIntegrationFragment auto-inject {}
+
+ // generator API
+ fragment = generator.GeneratorFragment auto-inject {}
+
+ // formatter API
+ fragment = formatting.FormatterFragment auto-inject {}
+
+ // labeling API
+ fragment = labeling.LabelProviderFragment auto-inject {}
+
+ // outline API
+ fragment = outline.OutlineTreeProviderFragment auto-inject {}
+ fragment = outline.QuickOutlineFragment auto-inject {}
+
+ // quickfix API
+ fragment = quickfix.QuickfixProviderFragment auto-inject {}
+
+ // content assist API
+ fragment = contentAssist.ContentAssistFragment auto-inject {}
+
+ // generates a more lightweight Antlr parser and lexer tailored for content assist
+ fragment = parser.antlr.XtextAntlrUiGeneratorFragment auto-inject {}
+
+ // generates junit test support classes into Generator#pathTestProject
+ fragment = junit.Junit4Fragment auto-inject {}
+
+ // rename refactoring
+ fragment = refactoring.RefactorElementNameFragment auto-inject {}
+
+ // provides the necessary bindings for java types integration
+ fragment = types.TypesGeneratorFragment auto-inject {}
+
+ // generates the required bindings only if the grammar inherits from Xbase
+ fragment = xbase.XbaseGeneratorFragment auto-inject {}
+
+ // provides a preference page for template proposals
+ fragment = templates.CodetemplatesGeneratorFragment auto-inject {}
+
+ // provides a compare view
+ fragment = compare.CompareFragment auto-inject {}
+
+ // parse grammar and generate i18n grammar
+ fragment = org.eclipse.osbp.xtext.basic.generator.BasicDslGrammarI18nGenerator auto-inject {}
+ }
+ }
+}
+
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/XcoreResourceFactory.java b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/XcoreResourceFactory.java
new file mode 100644
index 0000000..89ba47b
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/XcoreResourceFactory.java
@@ -0,0 +1,28 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+ package org.eclipse.osbp.xtext.datainterchange;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xcore.resource.XcoreResource;
+
+public class XcoreResourceFactory implements Resource.Factory {
+ @Override
+ public Resource createResource(URI uri) {
+ XcoreResource resource = new XcoreResource();
+ resource.setURI(uri);
+ return resource;
+ }
+
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/formatting/DataDSLFormatter.xtend b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/formatting/DataDSLFormatter.xtend
new file mode 100644
index 0000000..5a5b23a
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/formatting/DataDSLFormatter.xtend
@@ -0,0 +1,46 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ *
+ * This copyright notice shows up in the generated Java code
+ *
+ */
+
+package org.eclipse.osbp.xtext.datainterchange.formatting
+
+import com.google.inject.Inject;
+import org.eclipse.xtext.formatting.impl.AbstractDeclarativeFormatter
+import org.eclipse.xtext.formatting.impl.FormattingConfig
+import org.eclipse.osbp.utils.xtext.GenericFormatter
+import org.eclipse.xtext.xbase.services.XtypeGrammarAccess
+//import org.eclipse.osbp.xtext.datainterchange.services.DataDSLGrammarAccess
+
+/**
+ * This class contains custom formatting description.
+ *
+ * see : http://www.eclipse.org/Xtext/documentation.html#formatting
+ * on how and when to use it
+ *
+ * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an example
+ */
+class DataDSLFormatter extends AbstractDeclarativeFormatter {
+
+// @Inject extension DataDSLGrammarAccess
+ @Inject XtypeGrammarAccess grammarAccess
+
+ override protected void configureFormatting(FormattingConfig c) {
+ val genericFormatter = new GenericFormatter()
+
+ genericFormatter.formatFirstLevelBlocks( c, grammar.grammar, "DataInterchange", "DataInterchangeImport" )
+ genericFormatter.genericFormatting( c, grammar, grammarAccess )
+ }
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/jvmmodel/DataDSLJvmModelInferrer.xtend b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/jvmmodel/DataDSLJvmModelInferrer.xtend
new file mode 100644
index 0000000..724e1c9
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/jvmmodel/DataDSLJvmModelInferrer.xtend
@@ -0,0 +1,1055 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ *
+ * This copyright notice shows up in the generated Java code
+ *
+ */
+
+package org.eclipse.osbp.xtext.datainterchange.jvmmodel
+
+import com.vaadin.ui.Button
+import com.vaadin.ui.CssLayout
+import com.vaadin.ui.Label
+import com.vaadin.ui.VerticalLayout
+import java.io.OutputStream
+import java.net.URL
+import java.util.ArrayList
+import java.util.HashMap
+import java.util.Iterator
+import java.util.Locale
+import java.util.Map
+import java.util.concurrent.ExecutorService
+import javax.annotation.PostConstruct
+import javax.annotation.PreDestroy
+import javax.inject.Inject
+import javax.persistence.EntityManager
+import javax.xml.transform.Transformer
+import javax.xml.transform.TransformerFactory
+import org.eclipse.e4.core.contexts.IEclipseContext
+import org.eclipse.e4.core.services.events.IEventBroker
+import org.eclipse.e4.ui.model.application.MApplication
+import org.eclipse.osbp.dsl.entity.xtext.extensions.ModelExtensions
+import org.eclipse.osbp.dsl.semantic.common.types.LReference
+import org.eclipse.osbp.dsl.semantic.entity.LEntity
+import org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView
+import org.eclipse.osbp.persistence.IPersistenceService
+import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService
+import org.eclipse.osbp.ui.api.user.IUser
+import org.eclipse.osbp.utils.constants.GeneratorConstants
+import org.eclipse.osbp.utils.entitymock.IEntityImportInitializationListener
+import org.eclipse.osbp.xtext.datainterchange.DataInterchange
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeBean
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFileCSV
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFileEDI
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFileXML
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangePackage
+import org.eclipse.osbp.xtext.datainterchange.common.WorkerThreadRunnable
+import org.eclipse.osbp.xtext.i18n.DSLOutputConfigurationProvider
+import org.eclipse.xtext.common.types.JvmDeclaredType
+import org.eclipse.xtext.common.types.JvmField
+import org.eclipse.xtext.common.types.JvmGenericType
+import org.eclipse.xtext.common.types.JvmVisibility
+import org.eclipse.xtext.naming.IQualifiedNameProvider
+import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
+import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
+import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
+import org.milyn.Smooks
+import org.milyn.SmooksFactory
+import org.milyn.container.ExecutionContext
+import org.osgi.framework.BundleEvent
+import org.osgi.framework.BundleListener
+import org.osgi.service.event.EventHandler
+import org.slf4j.Logger
+
+/**
+ * <p>
+ * Data Interchange Repository Domain Specific Language
+ * This inferrer infers models of extension .data and generates code to be used by any data interchanging process
+ * to facilitate the communication with external data sources and drains. Underlying components
+ * are from the smooks repository
+ * </p>
+ *
+ * @author Joerg Riegel
+ */
+
+class DataDSLJvmModelInferrer extends AbstractModelInferrer {
+
+ @Inject extension JvmTypesBuilder
+ @Inject extension IQualifiedNameProvider
+ @Inject extension DataDSLModelGenerator dg
+ @Inject extension ModelExtensions
+
+ /* ramp up NTHREADS and threads are finished start more but up to this limit */
+ var NTHREADS = 10;
+
+ /**
+ * infer model on package base. Will be called for every defined package.
+ *
+ * @param dataInterchangePackage
+ * An instance of {@link DataInterchangePackage}
+ * @param acceptor
+ * the xtext acceptor interface
+ * @param isPreIndexingPhase
+ * true if in preindexing phase
+ */
+ def dispatch void infer(DataInterchangePackage dataInterchangePackage, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
+ dataInterchangePackage.generatePckgName(acceptor)
+ // create a view
+ var cls = dataInterchangePackage.toClass(dataInterchangePackage.name.toString.concat("TriggerView"));
+ cls.simpleName = cls.simpleName.toFirstUpper
+ acceptor.accept(cls,
+ [
+ superTypes += _typeReferenceBuilder.typeRef(AbstractHybridVaaclipseView)
+ superTypes += _typeReferenceBuilder.typeRef(BundleListener)
+ superTypes += _typeReferenceBuilder.typeRef(IUser.UserLocaleListener)
+ documentation = GeneratorConstants.GENERATED_CLASSES_DOCUMENTATION
+ annotations += _annotationTypesBuilder.annotationRef(SuppressWarnings, "serial")
+ packageName = dataInterchangePackage.fullyQualifiedName.toString
+ it.toFields(dataInterchangePackage)
+ it.toConstructor(dataInterchangePackage)
+ it.toOperations(dataInterchangePackage)
+ ])
+
+ // create smooks classes
+ for (dataInterchange : dataInterchangePackage.datInts) {
+ var clsName2 = dataInterchange.fullyQualifiedName
+ acceptor.accept(dataInterchange.toClass(clsName2),
+ [
+ superTypes += _typeReferenceBuilder.typeRef(WorkerThreadRunnable)
+ annotations += _annotationTypesBuilder.annotationRef(SuppressWarnings, "serial")
+ documentation = GeneratorConstants.GENERATED_CLASSES_DOCUMENTATION
+ it.toConstructor(dataInterchange)
+ it.toFields(dataInterchange)
+ it.toOperations(dataInterchange)
+ ])
+ }
+ }
+
+
+ /**
+ * generate the fields in the inferred class.
+ *
+ * @param type
+ * the xtext generic types list
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ */
+ def void toFields(JvmGenericType type, DataInterchangePackage pkg) {
+ var JvmField field = null
+ field = pkg.toField("sidebar", _typeReferenceBuilder.typeRef(VerticalLayout))
+ type.members += field
+ var name = pkg.name.toString.replace(".",":")
+ var String[] parts = name.split(":")
+ val String clsName = parts.get(parts.size-1).toFirstUpper
+ field = pkg.toField("log", _typeReferenceBuilder.typeRef(Logger)) [setInitializer([ append('''LoggerFactory.getLogger(«clsName»TriggerView.class)''') ])]
+ field.final = true
+ field.static = true
+ type.members += field
+ field = pkg.toField("menu", _typeReferenceBuilder.typeRef(CssLayout))
+ type.members += field
+ field = pkg.toField("workerInfo", _typeReferenceBuilder.typeRef(EventHandler))
+ type.members += field
+ field = pkg.toField("branding", _typeReferenceBuilder.typeRef(CssLayout))
+ type.members += field
+ field = pkg.toField("eventBroker", _typeReferenceBuilder.typeRef(IEventBroker)) [
+ annotations += _annotationTypesBuilder.annotationRef(Inject)
+ ]
+ type.members += field
+
+ field = pkg.toField("persistenceService", _typeReferenceBuilder.typeRef(IPersistenceService)) [
+ annotations += _annotationTypesBuilder.annotationRef(Inject)
+ ]
+ type.members += field
+
+ field = pkg.toField("progressBars", _typeReferenceBuilder.typeRef(Map, _typeReferenceBuilder.typeRef(String), _typeReferenceBuilder.typeRef(WorkerThreadRunnable)))
+ type.members += field
+ field = pkg.toField("executorService", _typeReferenceBuilder.typeRef(ExecutorService))
+ field.static = true
+ type.members += field
+ field = pkg.toField("dslMetadataService", _typeReferenceBuilder.typeRef(IDSLMetadataService)) [annotations += _annotationTypesBuilder.annotationRef(Inject)]
+ type.members += field
+ field = pkg.toField("user", _typeReferenceBuilder.typeRef(IUser))[annotations += _annotationTypesBuilder.annotationRef(Inject)]
+ type.members += field
+ field = pkg.toField("logo", _typeReferenceBuilder.typeRef(Label))
+ type.members += field
+ field = pkg.toField("buttons",
+ _typeReferenceBuilder.typeRef(HashMap, _typeReferenceBuilder.typeRef(Button), _typeReferenceBuilder.typeRef(ArrayList)))
+ type.members += field
+ }
+
+ /**
+ * <p>build the constructors to be used by an e4 application.</p>
+ *
+ */
+ def void toConstructor(JvmDeclaredType type, DataInterchangePackage pkg) {
+ type.members += pkg.toConstructor([
+ annotations += _annotationTypesBuilder.annotationRef(Inject)
+ parameters += pkg.toParameter("parent", _typeReferenceBuilder.typeRef(VerticalLayout))
+ parameters += pkg.toParameter("context", _typeReferenceBuilder.typeRef(IEclipseContext))
+ parameters += pkg.toParameter("app", _typeReferenceBuilder.typeRef(MApplication))
+ body = [ append('''super(parent,context,app);''')]
+ ])
+ }
+
+ /**
+ * generate the fields in the inferred class.
+ *
+ * @param type
+ * the xtext generic types list
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ */
+ def void toOperations(JvmGenericType type, DataInterchangePackage pkg) {
+ // create view
+ type.members += pkg.toMethod("createView", _typeReferenceBuilder.typeRef(Void::TYPE), [
+ parameters += pkg.toParameter("parent", _typeReferenceBuilder.typeRef(VerticalLayout))
+ body = [ append('''«pkg.createView»''')]
+ ])
+ // create components
+ type.members += pkg.toMethod("createComponents", _typeReferenceBuilder.typeRef(Void::TYPE), [
+ body = [ append('''«pkg.createComponents»''')]
+ ])
+ // unique name
+ type.members += pkg.toMethod("uniqueName", _typeReferenceBuilder.typeRef(String), [
+ parameters += pkg.toParameter("name", _typeReferenceBuilder.typeRef(String))
+ body = [ append('''«pkg.uniqueName»''')]
+ ])
+ // is duplicate
+ type.members += pkg.toMethod("isDuplicate", _typeReferenceBuilder.typeRef(boolean), [
+ parameters += pkg.toParameter("name", _typeReferenceBuilder.typeRef(String))
+ body = [ append('''«pkg.isDuplicate»''')]
+ ])
+ // find layout
+ type.members += pkg.toMethod("findButtonLayout", _typeReferenceBuilder.typeRef(VerticalLayout), [
+ parameters += pkg.toParameter("button", _typeReferenceBuilder.typeRef(Button))
+ body = [ append('''«pkg.findButtonLayout»''')]
+ ])
+ // on bundle stopping - shutdown executorService
+ type.members += pkg.toMethod("bundleChanged", _typeReferenceBuilder.typeRef(Void::TYPE), [
+ annotations += _annotationTypesBuilder.annotationRef(Override)
+ parameters += pkg.toParameter("event", _typeReferenceBuilder.typeRef(BundleEvent))
+ body = [ append('''«pkg.bundleChanged»''')]
+ ])
+ // subscribe to eventBroker
+ type.members += pkg.toMethod("subscribe", _typeReferenceBuilder.typeRef(Void::TYPE), [
+ visibility = JvmVisibility.PROTECTED
+ annotations += _annotationTypesBuilder.annotationRef(PostConstruct)
+ body = [append('''«pkg.subscribe»''')]
+ ])
+ // unsubscribe from eventBroker
+ type.members += pkg.toMethod("unsubscribe", _typeReferenceBuilder.typeRef(Void::TYPE), [
+ visibility = JvmVisibility.PROTECTED
+ annotations += _annotationTypesBuilder.annotationRef(PreDestroy)
+ body = [append('''«pkg.unsubscribe»''')]
+ ])
+ // locale notification
+ type.members += pkg.toMethod("localeChanged", _typeReferenceBuilder.typeRef(Void::TYPE),
+ [
+ visibility = JvmVisibility.PUBLIC
+ annotations += _annotationTypesBuilder.annotationRef(Override)
+ parameters += pkg.toParameter("locale", _typeReferenceBuilder.typeRef(Locale))
+ body = [append('''«pkg.localeChanged»''')]
+ ])
+ }
+
+ /**
+ * handle the worker progress UI. provide the appropriate code.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String workerInfo(DataInterchangePackage pkg) {
+ var body = ""
+ body = '''
+ «body»
+ new EventHandler() {
+ @Override
+ public void handleEvent(Event event) {
+ // a worker notified this view that it is finished
+ String workername = (String)event.getProperty(EventUtils.DATA);
+ if (progressBars.containsKey(workername)) {
+ final WorkerThreadRunnable worker = progressBars.get(workername);
+ ((VerticalLayout)worker.getProgressBarArea().getParent()).removeComponent(worker.getProgressBarArea());
+ progressBars.remove(workername);
+ }
+ }
+ };
+ '''
+ return body
+ }
+
+ /**
+ * subscribe the event broker for messages on changed locale and worker progress.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String subscribe(DataInterchangePackage pkg) {
+ var body = ""
+ body = '''
+ «body»
+ eventBroker.subscribe(EventBrokerMsg.WORKER_THREAD_INFO, workerInfo);
+ '''
+ return body
+ }
+
+ /**
+ * unsubscribe from event broker for messages.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String unsubscribe(DataInterchangePackage pkg) {
+ var body = ""
+ body = '''
+ «body»
+ eventBroker.unsubscribe(workerInfo);
+ '''
+ return body
+ }
+
+ /**
+ * normalize package name.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return normalized package name
+ */
+ def String toEventID(DataInterchangePackage pkg) {
+ return pkg.fullyQualifiedName.toString.toUpperCase.replaceAll("(\\W)","_")
+ }
+
+ /**
+ * let the app wait for finishing the workers before allowing to stop bundle.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String bundleChanged(DataInterchangePackage pkg) {
+ var body = ""
+ body = '''
+ «body»
+ if (event.getType() == BundleEvent.STOPPING) {
+ log.debug("bundle is stopping");
+ // This will make the executorService accept no new threads
+ // and finish all existing threads in the queue
+ if (executorService != null) {
+ executorService.shutdown();
+ // Wait until all threads are finished
+ try {
+ executorService.awaitTermination(10, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ log.debug("all executors finished");
+ }
+ '''
+ return body
+ }
+
+ /**
+ * find the right button layout for a given button.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String findButtonLayout(DataInterchangePackage pkg) {
+ var body = ""
+ body = '''
+ «body»
+ int count = menu.getComponentCount();
+ for(int i=0; i<count; i++) {
+ VerticalLayout buttonLayout = (VerticalLayout)menu.getComponent(i);
+ Button b = (Button)buttonLayout.getComponent(0);
+ if (b == button) {
+ return buttonLayout;
+ }
+ }
+ return null;
+ '''
+ return body
+ }
+
+ /**
+ * find out if a given thread-id is already running.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String isDuplicate(DataInterchangePackage pkg) {
+ var body = ""
+ body = '''
+ «body»
+ boolean found = false;
+ for(String threadName : progressBars.keySet()) {
+ if (name.equals(threadName)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ '''
+ return body
+ }
+
+ /**
+ * make a name unique by concatenating a number.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String uniqueName(DataInterchangePackage pkg) {
+ var body = ""
+ body = '''
+ «body»
+ Integer cnt = 0;
+ String searchName;
+ do {
+ if (cnt > 0) {
+ searchName = name+cnt.toString();
+ } else {
+ searchName = name;
+ }
+ cnt ++;
+ }while(isDuplicate(searchName));
+ return searchName;
+ '''
+ return body
+ }
+
+ def String descriptionI18nKey(DataInterchange dataInterchange) {
+ if ((dataInterchange.descriptionValue == null) || dataInterchange.descriptionValue.isEmpty) {
+ dataInterchange.name
+ }
+ else {
+ dataInterchange.descriptionValue
+ }
+ }
+
+ /**
+ * build an e4 compatible view and create necessary components.
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String createView(DataInterchangePackage pkg) {
+ var body = '''
+ buttons = new HashMap<Button, ArrayList>();
+ workerInfo = «pkg.workerInfo»
+ Bundle bundle = FrameworkUtil.getBundle(getClass());
+ if (bundle != null) {
+ BundleContext ctx = bundle.getBundleContext();
+ if (ctx != null) {
+ ctx.addBundleListener(this);
+ }
+ }
+ FrameworkUtil.getBundle(getClass()).getBundleContext().addBundleListener(this);
+ executorService = Executors.newFixedThreadPool(«NTHREADS»);
+ progressBars = new HashMap<String,WorkerThreadRunnable>();
+ sidebar=new VerticalLayout();
+ menu=new CssLayout();
+ branding=new CssLayout();
+ parent.setPrimaryStyleName("osbp");
+ parent.setId("parent");
+ parent.setSizeFull();
+ sidebar.setSpacing(true);
+ sidebar.setId("sidebar");
+ parent.addComponent(sidebar);
+ parent.setExpandRatio(sidebar, 1.0f);
+ // create sidebar
+ sidebar.addStyleName("osbpsidebar");
+ sidebar.setSizeFull();
+ sidebar.addComponent(branding);
+ // branding title
+ branding.addStyleName("branding");
+ logo = new Label();
+ logo.setContentMode(ContentMode.HTML);
+ logo.setSizeUndefined();
+ branding.addComponent(logo);
+ // add menu
+ sidebar.addComponent(menu);
+ sidebar.setExpandRatio(menu, 1.0f);
+
+ '''
+ body = '''«body»
+ // add menu items
+ Button b;
+ VerticalLayout buttonLayout;
+ '''
+ for (dataInterchange : pkg.datInts) {
+ body = '''
+ «body»
+ b = new NativeButton();
+ b.setHtmlContentAllowed(true);
+ buttons.put(b, new ArrayList<String>(Arrays.asList(new String[] {"«DataDSLModelGenerator.CAPTION__REPFIX_I18NKEY_IMPORT»", "«dataInterchange.name»","«dataInterchange.descriptionI18nKey»"})));
+ b.addStyleName("icon-download");
+ b.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.debug("pressed «dataInterchange.name» import");
+ String uniqueName = uniqueName("«dataInterchange.name»");
+ «dataInterchange.getBasicRunConfiguration(false, dataInterchange.getFileURL)»
+ «dataInterchange.defaultVariableName».setName(uniqueName);
+ «dataInterchange.defaultVariableName».setEventBroker(eventBroker);
+ «dataInterchange.defaultVariableName».setUi(UI.getCurrent());
+ «dataInterchange.defaultVariableName».setDirection(WorkerThreadRunnable.Direction.IMPORT);
+ «IF dataInterchange.progressBarStyle!=null»«dataInterchange.defaultVariableName».setProgressBarStyleName("«dataInterchange.progressBarStyle.literal»");«ENDIF»
+ findButtonLayout(event.getButton()).addComponent(«dataInterchange.defaultVariableName».getProgressBarArea());
+ progressBars.put(uniqueName, «dataInterchange.defaultVariableName»);
+ executorService.execute(«dataInterchange.defaultVariableName»);
+ log.debug("«dataInterchange.name» import added to executor queue");
+ }
+ });
+ buttonLayout = new VerticalLayout();
+ buttonLayout.addComponent(b);
+ menu.addComponent(buttonLayout);
+ '''
+ body = '''
+ «body»
+ b = new NativeButton();
+ b.setHtmlContentAllowed(true);
+ buttons.put(b, new ArrayList<String>(Arrays.asList(new String[] {"«DataDSLModelGenerator.CAPTION__REPFIX_I18NKEY_EXPORT»", "«dataInterchange.name»","«dataInterchange.descriptionI18nKey»"})));
+ b.addStyleName("icon-upload");
+ b.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.debug("pressed «dataInterchange.name» export");
+ String uniqueName = uniqueName("«dataInterchange.name»");
+ «dataInterchange.getBasicRunConfiguration(false, dataInterchange.getFileURL)»
+ «dataInterchange.defaultVariableName».setName(uniqueName);
+ «dataInterchange.defaultVariableName».setEventBroker(eventBroker);
+ «dataInterchange.defaultVariableName».setUi(UI.getCurrent());
+ «dataInterchange.defaultVariableName».setDirection(WorkerThreadRunnable.Direction.EXPORT);
+ «IF dataInterchange.progressBarStyle!=null»«dataInterchange.defaultVariableName».setProgressBarStyleName("«dataInterchange.progressBarStyle.literal»");«ENDIF»
+ findButtonLayout(event.getButton()).addComponent(«dataInterchange.defaultVariableName».getProgressBarArea());
+ progressBars.put(uniqueName, «dataInterchange.defaultVariableName»);
+ executorService.execute(«dataInterchange.defaultVariableName»);
+ log.debug("«dataInterchange.name» export added to executor queue");
+ }
+ });
+ buttonLayout = new VerticalLayout();
+ buttonLayout.addComponent(b);
+ menu.addComponent(buttonLayout);
+ '''
+ }
+ body = '''
+ «body»
+ menu.addStyleName("menu");
+ menu.setHeight("100%");
+ user.addUserLocaleListener(this);
+ '''
+ return body
+ }
+
+ def String getDefaultVariableName(DataInterchange dataInterchange) {
+ return dataInterchange.name.toFirstLower
+ }
+
+ def String getBasicRunConfiguration(DataInterchange dataInterchange, boolean fqClass, String fileURL) {
+ var className = ""
+ if (fqClass) {
+ className = dataInterchange.fullyQualifiedName.toString
+ }
+ else {
+ className = dataInterchange.name
+ }
+ return '''
+ «className» «dataInterchange.getDefaultVariableName» = new «className»();
+ «dataInterchange.getDefaultVariableName».setFileURL("«fileURL»");
+ «dataInterchange.getDefaultVariableName».setPersistenceService(persistenceService);
+ '''
+ }
+
+ def String getFileURL(DataInterchange dataInterchange) {
+ switch(dataInterchange.fileEndpoint) {
+ DataInterchangeFileXML: return (dataInterchange.fileEndpoint as DataInterchangeFileXML).fileURL
+ DataInterchangeFileCSV: return (dataInterchange.fileEndpoint as DataInterchangeFileCSV).fileURL
+ DataInterchangeFileEDI: return (dataInterchange.fileEndpoint as DataInterchangeFileEDI).fileURL
+ }
+ return ""
+ }
+
+ /**
+ * create more components. this fragment is repainted if something changes (e.g. language)
+ *
+ * @param pkg
+ * the current package inferred {@link DataInterchangePackage}
+ * @return code fragment
+ */
+ def String createComponents(DataInterchangePackage pkg) {
+ return ""
+ }
+
+ /**
+ * <p>build the constructor for each smooks class.</p>
+ *
+ * @param pkg
+ * the current datainterchange inferred {@link DataInterchange}
+ */
+ def void toConstructor(JvmDeclaredType type, DataInterchange dataInterchange) {
+ type.members += dataInterchange.toConstructor([
+ body = [append('''
+ setName("«dataInterchange.name»");
+ ''')]
+ ])
+ }
+
+ /**
+ * <p>build the class variables.</p>
+ *
+ */
+ def void toFields(JvmDeclaredType type, DataInterchange dataInterchange) {
+ var JvmField field = null
+ field = dataInterchange.toField("log", _typeReferenceBuilder.typeRef(Logger)) [setInitializer([ append('''LoggerFactory.getLogger("dataInterchange")''') ])]
+ field.final = true
+ field.static = true
+ type.members += field
+ field = dataInterchange.toField("smooksOSGIFactory", _typeReferenceBuilder.typeRef(SmooksFactory)) [setInitializer([ append('''null''') ])]
+ type.members += field
+ field = dataInterchange.toField("smooks", _typeReferenceBuilder.typeRef(Smooks))
+ type.members += field
+// field = dataInterchange.toField("xmlBinding", _typeReferenceBuilder.typeRef(XMLBinding))
+// type.members += field
+ field = dataInterchange.toField("em", _typeReferenceBuilder.typeRef(EntityManager))
+ type.members += field
+ field = dataInterchange.toField("fileURL", _typeReferenceBuilder.typeRef(URL))
+ type.members += field
+ field = dataInterchange.toField("executionContext", _typeReferenceBuilder.typeRef(ExecutionContext))
+ type.members += field
+ field = dataInterchange.toField("file", _typeReferenceBuilder.typeRef(OutputStream))
+ type.members += field
+ field = dataInterchange.toField("out", _typeReferenceBuilder.typeRef(OutputStream))
+ type.members += field
+ field = dataInterchange.toField("pollingInterval", _typeReferenceBuilder.typeRef(int)) [setInitializer([ append('''500''') ])]
+ type.members += field
+ field = dataInterchange.toField("transformerFactory", _typeReferenceBuilder.typeRef(TransformerFactory)) [setInitializer([ append('''TransformerFactory.newInstance()''') ])]
+ type.members += field
+ field = dataInterchange.toField("transformer", _typeReferenceBuilder.typeRef(Transformer))
+ type.members += field
+ }
+
+ /**
+ * <p>build the methods.</p>
+ *
+ */
+ def void toOperations(JvmDeclaredType type, DataInterchange dataInterchange) {
+ type.members += dataInterchange.toMethod("run", _typeReferenceBuilder.typeRef(Void::TYPE), [
+ annotations += _annotationTypesBuilder.annotationRef(Override)
+ body = [ append('''run(null);''')]
+ ])
+ type.members += dataInterchange.toMethod("run", _typeReferenceBuilder.typeRef(Void::TYPE), [
+ parameters += dataInterchange.toParameter("importListener", _typeReferenceBuilder.typeRef(IEntityImportInitializationListener))
+ body = [ append('''«dataInterchange.performSmooks»''')]
+ ])
+ type.members += dataInterchange.toMethod("init", _typeReferenceBuilder.typeRef(boolean), [
+ visibility = JvmVisibility.PROTECTED
+ parameters += dataInterchange.toParameter("direction", _typeReferenceBuilder.typeRef(WorkerThreadRunnable.Direction))
+ body = [ append('''«dataInterchange.init»''')]
+ ])
+ type.members += dataInterchange.toMethod("setFileURL", _typeReferenceBuilder.typeRef(Void::TYPE), [
+ parameters += dataInterchange.toParameter("filePath", _typeReferenceBuilder.typeRef(String))
+ body = [ append('''«dataInterchange.fileUrl»''')]
+ ])
+ }
+
+ /**
+ * <p>create URL from filepath or other string.</p>
+ *
+ * @param pkg
+ * the current datainterchange inferred {@link DataInterchange}
+ * @return code fragment
+ */
+ def fileUrl(DataInterchange dataInterchange)
+ '''
+ fileURL = null;
+ String path = filePath;
+ if (filePath.startsWith("file://") && !org.eclipse.osbp.utils.common.SystemInformation.isMacOS()) {
+ path = filePath.substring("file://".length());
+ }
+ try {
+ fileURL = new URL(path);
+ } catch (MalformedURLException e1) {
+ if(e1.getMessage().startsWith("unknown protocol")) {
+ try {
+ fileURL = Paths.get(path).toUri().toURL();
+ } catch (MalformedURLException e2) {
+ log.error(e2.getLocalizedMessage()+e2.getCause());
+ }
+ }
+ }
+ '''
+
+ /**
+ * init smooks factory to create the core import process.
+ * setup listeners for UI communication.
+ * setup persistence layer.
+ *
+ * @param pkg
+ * the current datainterchange inferred {@link DataInterchange}
+ * @return code fragment
+ */
+ def String init(DataInterchange dataInterchange) {
+ var firstEntity = (dataInterchange.path.iterator.next as DataInterchangeBean)
+ var body =
+ '''
+ if(getEventBroker()!=null) {
+ pollingInterval = UI.getCurrent().getPollInterval();
+ UI.getCurrent().setPollInterval(500);
+ }
+ try {
+ transformerFactory.setAttribute("indent-number", 4);
+ transformer = transformerFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+ transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
+ transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml");
+
+ // init smooks
+ setProgressBarEnabled(true);
+ setProgressIndeterminated(true);
+ if (log.isDebugEnabled()) log.debug("initializing smooks factory");
+ smooksOSGIFactory = new SmooksOSGIFactory(FrameworkUtil.getBundle(this.getClass()));
+ smooks = smooksOSGIFactory.createInstance(FrameworkUtil.getBundle(this.getClass()).getResource("«DSLOutputConfigurationProvider.SMOOKS_OUTPUT_DIRECTORY»/«dataInterchange.name»-"+direction.toString().toLowerCase()+".xml").openStream());
+ // prepare execution context
+ executionContext = smooks.createExecutionContext();
+ executionContext.setEventListener(this);
+ // get entity manager
+ if (log.isDebugEnabled()) log.debug("opening entity manager to persist smooks results");
+ getPersistenceService().registerPersistenceUnit("«firstEntity.entity.persistenceUnit»", «firstEntity.entity.fullyQualifiedName».class);
+ em = getPersistenceService().getEntityManagerFactory("«firstEntity.entity.persistenceUnit»").createEntityManager();
+ «IF dataInterchange.createReport»
+ // create a filtering report -- impacts performance
+ if (log.isDebugEnabled()) log.debug("reporting is on - impacting performance");
+ String location = FrameworkUtil.getBundle(this.getClass()).getLocation()+"«DSLOutputConfigurationProvider.SMOOKS_OUTPUT_DIRECTORY»/«dataInterchange.name»-"+direction.toString().toLowerCase()+"-report.html";
+ executionContext.setEventListener(new HtmlReportGenerator(location));
+ «ENDIF»
+ } catch (Exception e) {
+ if(getEventBroker()!=null) {
+ UI.getCurrent().setPollInterval(pollingInterval);
+ }
+ log.error(e.getLocalizedMessage()+e.getCause());
+ return false;
+ }
+ if(direction == Direction.EXPORT) {
+ int openTry = 0;
+ file = null;
+ URI uri = null;
+ try {
+ uri = fileURL.toURI();
+ } catch (URISyntaxException e) {
+ log.error(e.getLocalizedMessage()+e.getCause());
+ return false;
+ }
+ do {
+ Path path = null;
+ path = Paths.get(uri);
+ try {
+ // find a unique name - similar to given
+ file = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW);
+ } catch (FileAlreadyExistsException ae) {
+ openTry ++;
+ try {
+ uri = fileURL.toURI();
+ int pos = uri.getPath().lastIndexOf('.');
+ if(pos == -1) {
+ uri = new URI(uri.getScheme()+":"+uri.getPath()+openTry);
+ } else {
+ uri = new URI(uri.getScheme()+":"+uri.getPath().substring(0,pos)+openTry+"."+uri.getPath().substring(pos+1));
+ }
+ } catch (URISyntaxException e) {
+ log.error(e.getLocalizedMessage()+e.getCause());
+ return false;
+ }
+ } catch (IOException e) {
+ log.error(e.getLocalizedMessage()+e.getCause());
+ return false;
+ }
+ }while(file == null);
+ out = new BufferedOutputStream(file);
+ }
+ return true;
+ '''
+ return body
+ }
+
+ /**
+ * use smooks factory to create the core import process.
+ * setup listeners for UI communication.
+ * setup persistence layer.
+ *
+ * @param pkg
+ * the current datainterchange inferred {@link DataInterchange}
+ * @return code fragment
+ */
+ def String performSmooks(DataInterchange dataInterchange) {
+ var firstEntity = (dataInterchange.path.iterator.next as DataInterchangeBean)
+ var body = '''
+ if(!init(getDirection())) {
+ return;
+ }
+ try {
+ if(getDirection()==WorkerThreadRunnable.Direction.IMPORT) {
+ '''
+ body = '''
+ «body»
+ if (importListener != null) {
+ importListener.notifyInitializationStep("datainterchange «dataInterchange.name.toFirstUpper» load.", 0.4, 0.45, 0, 0);
+ }
+ // execute the smooks filtering
+ JavaResult result = new JavaResult();
+ InputStream in = fileURL.openStream();
+ byte[] contents = StreamUtils.readStream(in);
+ setLength(contents.length);
+ setAvgElementSize(«IF dataInterchange.elementSize==0»10«ELSE»«dataInterchange.elementSize»«ENDIF»);
+ StreamSource source = new StreamSource(new ByteArrayInputStream(contents));
+ '''
+ for (path:dataInterchange.path) {
+ for (lookup:path.lookup) {
+ if (lookup.cached) {
+ body = '''
+ «body»
+ em.setProperty(PersistenceUnitProperties.CACHE_SIZE_+"«lookup.entity.fullyQualifiedName»", "«lookup.cacheSize»");
+ '''
+ }
+ }
+ }
+ body = '''
+ «body»
+ PersistenceUtil.setDAORegister(executionContext, new EntityManagerRegister(em));
+ // execute smooks filtering
+ if (log.isDebugEnabled()) log.debug("filtering starts");
+ setProgressIndeterminated(false);
+ if (importListener != null) {
+ importListener.notifyInitializationStep("datainterchange Warehouses load..", 0.4, 0.47, 0, 0);
+ }
+ smooks.filterSource(executionContext, source, result);
+ if (importListener != null) {
+ importListener.notifyInitializationStep("datainterchange Warehouses load...", 0.4, 0.48, 0, 0);
+ }
+ if (log.isDebugEnabled()) log.debug("smooks filtering finished");
+ '''
+ if (firstEntity.recordList) {
+ body = '''
+ «body»
+ // retrieve bean list
+ List<«firstEntity.entity.fullyQualifiedName»> «firstEntity.entity.name.toFirstLower»List = Arrays.asList((«firstEntity.entity.fullyQualifiedName»[]) result.getBean("«firstEntity.entity.name»List"));
+ // persist
+ em.getTransaction().begin();
+ if (log.isDebugEnabled()) log.debug("persisting results");
+ int total = «firstEntity.entity.name.toFirstLower»List.size();
+ int count = 0;
+ long lastStep = System.currentTimeMillis();
+ if (importListener != null) {
+ importListener.notifyInitializationStep("datainterchange «dataInterchange.name.toFirstUpper»", 0.4, 0.5, count, total);
+ }
+ for(«firstEntity.entity.fullyQualifiedName» «firstEntity.entity.name.toFirstLower»:«firstEntity.entity.name.toFirstLower»List) {
+ try {
+ em.persist(«firstEntity.entity.name.toFirstLower»);
+ }
+ catch (ConstraintViolationException cve) {
+ log.error("«firstEntity.entity.name.toFirstLower» #"+(count+1)+"/"+total+": "+cve.getLocalizedMessage());
+ for (ConstraintViolation violation : cve.getConstraintViolations()) {
+ Object value = violation.getInvalidValue();
+ if (value == null) {
+ value = "<null>";
+ }
+ log.error("- property:"
+ +violation.getLeafBean().toString()+"."+violation.getPropertyPath().toString()
+ +" value:'"+value.toString()
+ +" violation:"+violation.getMessage());
+ }
+ }
+ count++;
+ long thisStep = System.currentTimeMillis();
+ if ((importListener != null) && ((count % importListener.getInitializationSubStepNotifySize() == 0) || (thisStep-lastStep > 2500))) {
+ lastStep = System.currentTimeMillis();
+ importListener.notifyInitializationStep("datainterchange «dataInterchange.name.toFirstUpper»", 0.4, 0.5, count, total);
+ }
+ }
+ if (importListener != null) {
+ importListener.notifyInitializationStep("datainterchange «dataInterchange.name.toFirstUpper»", 0.4, 0.5, count, total);
+ }
+ if (log.isDebugEnabled()) log.debug("committing results");
+ em.getTransaction().commit();
+ '''
+ } else {
+ body = '''
+ «body»
+ // retrieve the root bean
+ «firstEntity.entity.fullyQualifiedName» «firstEntity.entity.name.toFirstLower» = («firstEntity.entity.fullyQualifiedName») result.getBean("«firstEntity.entity.name»");
+ // persist
+ em.getTransaction().begin();
+ if (log.isDebugEnabled()) log.debug("persisting results");
+ em.persist(«firstEntity.entity.name.toFirstLower»);
+ if (log.isDebugEnabled()) log.debug("committing results");
+ em.getTransaction().commit();
+ '''
+ }
+ if (firstEntity.markLatest) {
+ body = '''
+ «body»
+ if (log.isDebugEnabled()) log.debug("mark results as latest import");
+ em.setProperty(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.Lock);
+ em.getTransaction().begin();
+ em.createQuery("update «firstEntity.entity.name» set «firstEntity.latestProperty.name» = 0").executeUpdate();
+ em.createQuery("update «firstEntity.entity.name» set «firstEntity.latestProperty.name» = 1 where «»id= :id").setParameter("id", «firstEntity.entity.name.toFirstLower».getId()).executeUpdate();
+ if (log.isDebugEnabled()) log.debug("committing mark");
+ em.getTransaction().commit();
+ '''
+ }
+ if (dataInterchange.refreshEnabled) {
+ body = '''
+ «body»
+ if(getEventBroker()!=null) {
+ getEventBroker().send(EventBrokerMsg.REFRESH_VIEW+"«dataInterchange.refresh»", "*");
+ }
+ '''
+ }
+ body = '''
+ «body»
+ if (log.isDebugEnabled()) log.debug("results persisted");
+ '''
+ var iter = dataInterchange.path.iterator
+ var root = (iter.next as DataInterchangeBean).entity
+ body = '''
+ «body»
+ } else {
+ if (log.isDebugEnabled()) log.debug("prepare export");
+««« «IF dataInterchange.fileEndpoint instanceof DataInterchangeFileXML»
+««« // Create and initilise the XMLBinding instance...
+««« xmlBinding = new XMLBinding(smooks);
+««« xmlBinding.intiailize();
+««« xmlBinding.setOmitXMLDeclaration(true);
+««« «ENDIF»
+««« «dataInterchange.buildEntityGraph(iter, root)»
+ int pageNumber = 1;
+ int pageSize = 1000;
+ CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
+
+ if (log.isDebugEnabled()) log.debug("evaluate root entity count");
+ CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
+ countQuery.select(criteriaBuilder.count(countQuery.from(«firstEntity.entity.fullyQualifiedName».class)));
+ Long count = em.createQuery(countQuery).getSingleResult();
+ if (log.isDebugEnabled()) log.debug("root entity count is "+count.toString());
+ setLength(count*«IF dataInterchange.elementSize==0»10«ELSE»«dataInterchange.elementSize»«ENDIF»);
+ setAvgElementSize(1);
+
+ CriteriaQuery<«firstEntity.entity.fullyQualifiedName»> criteriaQuery = criteriaBuilder.createQuery(«firstEntity.entity.fullyQualifiedName».class);
+ Root<«firstEntity.entity.fullyQualifiedName»> from = criteriaQuery.from(«firstEntity.entity.fullyQualifiedName».class);
+ /* ... not necessary due to eager loading of entities via JPA ... «dataInterchange.buildJoins(iter, root)» ...*/
+ CriteriaQuery<«firstEntity.entity.fullyQualifiedName»> select = criteriaQuery.multiselect(from);
+
+ TypedQuery<«firstEntity.entity.fullyQualifiedName»> typedQuery = em.createQuery(select);
+««« typedQuery.setHint(QueryHints.JPA_LOAD_GRAPH, «firstEntity.entity.name.toFirstLower»Graph);
+ setProgressIndeterminated(false);
+ while (pageNumber < count.intValue()) {
+ if (log.isDebugEnabled()) log.debug("fetch and process entry "+pageNumber+" to "+(pageNumber+pageSize));
+ typedQuery.setFirstResult(pageNumber - 1);
+ typedQuery.setMaxResults(pageSize);
+ List<«firstEntity.entity.fullyQualifiedName»> queryResults = typedQuery.getResultList();
+««« «IF dataInterchange.fileEndpoint instanceof DataInterchangeFileCSV»
+ StringWriter writer = new StringWriter();
+ smooks.filterSource(executionContext, new JavaSource(queryResults), new StreamResult(writer));
+ out.write(writer.toString().getBytes());
+««« «ELSEIF dataInterchange.fileEndpoint instanceof DataInterchangeFileXML»
+««« for(«firstEntity.entity.fullyQualifiedName» row:queryResults) {
+««« String outXML = xmlBinding.toXML(row);
+««« out.write(outXML.getBytes());
+««« }
+««« JAXBContext jc = JAXBContext.newInstance(«firstEntity.entity.fullyQualifiedName».class);
+««« Marshaller marshaller = jc.createMarshaller();
+««« marshaller.marshal(queryResults, out);
+««« «ENDIF»
+ pageNumber += pageSize;
+ }
+ if (log.isDebugEnabled()) log.debug("export finished");
+ }
+ '''
+ body = '''
+ «body»
+ } catch (Exception e) {
+ log.error("«dataInterchange.name»: "+e.getLocalizedMessage()+e.getCause(), e);
+ } finally {
+ if(file != null) {
+ try {
+ out.close();
+ file.close();
+ } catch (IOException e) {
+ log.error(e.getLocalizedMessage()+e.getCause());
+ }
+ }
+ smooks.close();
+ if(getEventBroker()!=null) {
+ UI.getCurrent().setPollInterval(pollingInterval);
+ }
+ // close everything
+ if (em != null) {
+ em.close();
+ }
+ if (log.isDebugEnabled()) log.debug("datainterchange finished");
+ }
+ '''
+ return body
+ }
+
+ /**
+ * This seems to be not necessary, because JPA seems to load the entities eager itself!
+ * With this functionality active, the sql result set would contain all root entities multiple times!
+ */
+ @Deprecated
+ def buildJoins(DataInterchange interchange, Iterator<DataInterchangeBean> iter, LEntity rootEntity) {
+ var root = rootEntity
+ var body = ""
+ if(iter.hasNext) {
+ body = '''«body»from'''
+ }
+ while(iter.hasNext) {
+ var entity = (iter.next as DataInterchangeBean).entity
+ for(f:root.features) {
+ if (f instanceof LReference && f.toMany && f.type instanceof LEntity && f.type.toName.equals(entity.toName)) {
+ // one to many for the entity in sequence is found
+ body = '''«body».fetch("«f.name»", JoinType.LEFT)'''
+ }
+ }
+ root = entity
+ }
+ if(!body.empty) {
+ body = body + ";"
+ }
+ return body
+ }
+
+ def localeChanged(DataInterchangePackage pkg)
+ '''
+ «IF pkg.title != null»
+ if(logo != null) {
+ logo.setValue(dslMetadataService.translate(locale.toLanguageTag(), "«pkg.title»"));
+ }
+ «ENDIF»
+ if(buttons != null) {
+ for(Button button: buttons.keySet()) {
+ ArrayList i18nKeys = buttons.get(button);
+ button.setCaption(dslMetadataService.translate(locale.toLanguageTag(),(String)i18nKeys.get(1)));
+ button.setDescription(dslMetadataService.translate(locale.toLanguageTag(),(String)i18nKeys.get(0))+" "+dslMetadataService.translate(locale.toLanguageTag(),(String)i18nKeys.get(2)));
+ }
+ }'''
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/jvmmodel/DataDSLModelGenerator.xtend b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/jvmmodel/DataDSLModelGenerator.xtend
new file mode 100644
index 0000000..b67aa60
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/jvmmodel/DataDSLModelGenerator.xtend
@@ -0,0 +1,1060 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ *
+ * This copyright notice shows up in the generated Java code
+ *
+ */
+
+package org.eclipse.osbp.xtext.datainterchange.jvmmodel
+
+import com.google.common.collect.Lists
+import com.vaadin.shared.ui.label.ContentMode
+import com.vaadin.ui.Button
+import com.vaadin.ui.Button.ClickEvent
+import com.vaadin.ui.Button.ClickListener
+import com.vaadin.ui.HorizontalLayout
+import com.vaadin.ui.Label
+import com.vaadin.ui.NativeButton
+import com.vaadin.ui.ProgressBar
+import com.vaadin.ui.UI
+import java.io.BufferedOutputStream
+import java.io.ByteArrayInputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.StringReader
+import java.io.StringWriter
+import java.net.MalformedURLException
+import java.net.URI
+import java.net.URISyntaxException
+import java.net.URL
+import java.nio.file.FileAlreadyExistsException
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.Paths
+import java.nio.file.StandardOpenOption
+import java.text.MessageFormat
+import java.util.Arrays
+import java.util.HashMap
+import java.util.List
+import java.util.MissingResourceException
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+import javax.persistence.EntityManager
+import javax.persistence.EntityTransaction
+import javax.persistence.TypedQuery
+import javax.persistence.criteria.CriteriaBuilder
+import javax.persistence.criteria.CriteriaQuery
+import javax.persistence.criteria.JoinType
+import javax.persistence.criteria.Root
+import javax.validation.ConstraintViolation
+import javax.validation.ConstraintViolationException
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.transform.OutputKeys
+import javax.xml.transform.Transformer
+import javax.xml.transform.TransformerFactory
+import javax.xml.transform.dom.DOMSource
+import javax.xml.transform.stream.StreamResult
+import javax.xml.transform.stream.StreamSource
+import org.apache.commons.lang.StringEscapeUtils
+import org.eclipse.e4.core.di.extensions.EventUtils
+import org.eclipse.e4.core.services.events.IEventBroker
+import org.eclipse.emf.common.util.EList
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.emf.ecore.util.EcoreUtil
+import org.eclipse.osbp.dsl.entity.xtext.extensions.EntityTypesBuilder
+import org.eclipse.osbp.dsl.entity.xtext.extensions.ModelExtensions
+import org.eclipse.osbp.dsl.semantic.common.types.LAttribute
+import org.eclipse.osbp.dsl.semantic.common.types.LDataType
+import org.eclipse.osbp.dsl.semantic.common.types.LReference
+import org.eclipse.osbp.dsl.semantic.entity.LEntity
+import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute
+import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature
+import org.eclipse.osbp.eventbroker.EventBrokerMsg
+import org.eclipse.osbp.utils.entityhelper.DataType
+import org.eclipse.osbp.utils.entitymock.IEntityImportInitializationListener
+import org.eclipse.osbp.xtext.addons.EObjectHelper
+import org.eclipse.osbp.xtext.basic.generator.BasicDslGeneratorUtils
+import org.eclipse.osbp.xtext.datainterchange.DataInterchange
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeBean
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeEntityExpression
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFile
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFileCSV
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFileEDI
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFileXML
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFormat
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookup
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangePackage
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangePredefinedExpression
+import org.eclipse.osbp.xtext.datainterchange.common.WorkerThreadRunnable
+import org.eclipse.osbp.xtext.i18n.DSLOutputConfigurationProvider
+import org.eclipse.osbp.xtext.i18n.I18NModelGenerator
+import org.eclipse.persistence.config.PersistenceUnitProperties
+import org.eclipse.persistence.config.PessimisticLock
+import org.eclipse.persistence.config.QueryHints
+import org.eclipse.xtext.generator.IFileSystemAccess
+import org.eclipse.xtext.generator.IOutputConfigurationProvider
+import org.eclipse.xtext.naming.IQualifiedNameProvider
+import org.eclipse.xtext.naming.QualifiedName
+import org.eclipse.xtext.xbase.compiler.GeneratorConfig
+import org.eclipse.xtext.xbase.compiler.ImportManager
+import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
+import org.eclipse.osbp.ui.api.datamart.IDataMart.EType
+import org.milyn.Smooks
+import org.milyn.SmooksFactory
+import org.milyn.SmooksOSGIFactory
+import org.milyn.container.ExecutionContext
+import org.milyn.event.report.HtmlReportGenerator
+import org.milyn.event.types.ElementPresentEvent
+import org.milyn.event.types.FilterLifecycleEvent
+import org.milyn.event.types.FilterLifecycleEvent.EventType
+import org.milyn.io.StreamUtils
+import org.milyn.javabean.binding.xml.XMLBinding
+import org.milyn.payload.JavaResult
+import org.milyn.payload.JavaSource
+import org.milyn.payload.StringResult
+import org.milyn.persistence.util.PersistenceUtil
+import org.milyn.scribe.adapter.jpa.EntityManagerRegister
+import org.osgi.framework.Bundle
+import org.osgi.framework.BundleContext
+import org.osgi.framework.FrameworkUtil
+import org.osgi.service.event.Event
+import org.osgi.service.event.EventHandler
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.w3c.dom.Document
+import org.w3c.dom.Element
+
+class ParameterValue {
+ var public HashMap<String,String> modifiers = <String,String>newHashMap()
+ var public String value
+}
+
+class DataDSLModelGenerator extends I18NModelGenerator {
+ @Inject extension IQualifiedNameProvider
+ @Inject extension ModelExtensions
+ @Inject extension EntityTypesBuilder
+ @Inject extension IOutputConfigurationProvider outputConfig
+ @Inject extension BasicDslGeneratorUtils
+
+ @Inject
+ @Extension
+ private DataType dtType;
+
+ val static protected CAPTION__REPFIX_I18NKEY_EXPORT = "export"
+ val static protected CAPTION__REPFIX_I18NKEY_IMPORT = "import"
+
+ var public static String pckgName = null
+ val DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ val transformerFactory = TransformerFactory.newInstance()
+ var Transformer transformer = null
+ var db = dbf.newDocumentBuilder()
+ var domImpl = db.DOMImplementation
+
+ def String generateKey(String name, QualifiedName packageName) {
+ var pattern = "(\\W)"
+ if (name != null) {
+ var newName = name.replaceAll(pattern ,"_").toLowerCase
+ System.out.println(newName)
+ if (packageName != null) {
+ return packageName.toString.concat(".").concat(newName)
+ }
+ else {
+ return newName
+ }
+ }
+ return null
+ }
+
+ def void generatePckgName(DataInterchangePackage dip, IJvmDeclaredTypeAcceptor acceptor) {
+ pckgName = dip.getName
+ }
+
+ override doGenerate(Resource input, IFileSystemAccess fsa) {
+ addTranslatables('''«CAPTION__REPFIX_I18NKEY_EXPORT»,«CAPTION__REPFIX_I18NKEY_IMPORT»''')
+
+ // identation for pretty xml output
+ transformerFactory.setAttribute("indent-number", 4);
+ transformer = transformerFactory.newTransformer()
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes")
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8")
+ transformer.setOutputProperty(OutputKeys.STANDALONE, "yes")
+ transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml")
+
+ var configList = Lists.newArrayList(outputConfig.outputConfigurations)
+ var outputDirectory = ""
+ for(config:configList) {
+ if(config.name.equals(DSLOutputConfigurationProvider.SMOOKS_OUTPUT_ONCE)) {
+ outputDirectory = config.outputDirectory
+ }
+ }
+ EcoreUtil.getAllContents(EObjectHelper.getSemanticElement(input), false).filter(typeof(DataInterchange)).forEach[
+ // create all smooks config files
+ fsa.generateImportConfigStub(it)
+ fsa.generateExportConfigStub(it)
+ ]
+ super.doGenerate(input, fsa)
+ }
+
+ def void generateExportConfigStub(IFileSystemAccess fsa, DataInterchange dataInterchange) {
+ var body = ""
+ dbf.namespaceAware = true
+ var document = domImpl.createDocument("http://www.milyn.org/xsd/smooks-1.1.xsd", "smooks-resource-list", null)
+
+ var config = document.createElement("resource-config")
+ var selector = document.createAttribute("selector")
+ selector.textContent = "global-parameters"
+ config.attributeNode = selector;
+ var pEl = document.createElement("param");
+ var name = document.createAttribute("name")
+ name.textContent = "stream.filter.type"
+ pEl.attributeNode = name
+ var value = document.createTextNode("SAX")
+ pEl.appendChild(value)
+ config.appendChild(pEl)
+ document.documentElement.appendChild(config)
+
+ var cartridges = <String,String>newHashMap()
+ cartridges.put("xmlns:jb", "http://www.milyn.org/xsd/smooks/javabean-1.4.xsd")
+ switch (dataInterchange.fileEndpoint) {
+ DataInterchangeFileCSV: {
+ var delimiter = ""
+ var quote = ""
+ cartridges.put("xmlns:ftl", "http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd")
+ var csv = dataInterchange.fileEndpoint as DataInterchangeFileCSV
+ if(csv.delimiter != null) {
+ delimiter = StringEscapeUtils.unescapeHtml(csv.delimiter)
+ }
+ if(csv.quoteCharacter != null) {
+ quote = StringEscapeUtils.unescapeHtml(csv.quoteCharacter)
+ }
+ dataInterchange.generateExportConfig(document, dataInterchange.fileEndpoint, delimiter, quote)
+ }
+ DataInterchangeFileXML: {
+ cartridges.put("xmlns:ftl", "http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd")
+ dataInterchange.generateExportConfig(document, dataInterchange.fileEndpoint, null, null)
+ }
+ DataInterchangeFileEDI: {
+ }
+ }
+ for(cdg:cartridges.keySet) {
+ document.documentElement.setAttributeNS("http://www.w3.org/2000/xmlns/", cdg, cartridges.get(cdg))
+ }
+
+ var source = new DOMSource(document)
+ var res = new StringResult()
+ transformer.transform(source, res)
+ body = res.result
+ fsa.generateFile('''«dataInterchange.name»-«WorkerThreadRunnable.Direction.EXPORT.toString().toLowerCase()».xml''', DSLOutputConfigurationProvider.SMOOKS_OUTPUT_ONCE, body)
+ }
+
+ def void generateImportConfigStub(IFileSystemAccess fsa, DataInterchange dataInterchange) {
+ var body = ""
+ dbf.namespaceAware = true
+ var db = dbf.newDocumentBuilder()
+ var domImpl = db.DOMImplementation
+ var document = domImpl.createDocument("http://www.milyn.org/xsd/smooks-1.1.xsd", "smooks-resource-list", null)
+
+ var fieldList = <LEntityAttribute>newArrayList()
+ var cartridges = <String,String>newHashMap()
+ var parameters = <String,ParameterValue>newHashMap()
+ // for the meaning of cartridges see: http://www.smooks.org/mediawiki/index.php?title=V1.5:Smooks_v1.5_User_Guidecartridges
+ cartridges.put("xmlns:jb", "http://www.milyn.org/xsd/smooks/javabean-1.2.xsd")
+ cartridges.put("xmlns:dao", "http://www.milyn.org/xsd/smooks/persistence-1.2.xsd")
+ var pval = new ParameterValue
+ pval.value = "SAX"
+ parameters.put("stream.filter.type", pval)
+ // the smooks.visitor.sort=false removes NPE when using dao:lookup according to:
+ // http://milyn.996300.n3.nabble.com/jira-Created-MILYN-265-Add-support-for-Producer-Consumer-based-sorting-of-Visitor-logic-td3387.html
+ pval = new ParameterValue
+ pval.value = "false"
+ parameters.put("smooks.visitors.sort", pval)
+
+ switch (dataInterchange.fileEndpoint) {
+ DataInterchangeFileXML: {
+ // set input type and active filename
+ pval = new ParameterValue
+ pval.value = "input.xml"
+ parameters.put("inputType", pval)
+ pval = new ParameterValue
+ pval.value = (dataInterchange.fileEndpoint as DataInterchangeFileXML).fileURL
+ pval.modifiers.put("type", "input.type.actived")
+ parameters.put("input.xml", pval)
+ dataInterchange.generateImportConfig(fieldList, document, dataInterchange.fileEndpoint)
+ (dataInterchange.fileEndpoint as DataInterchangeFileXML).input(dataInterchange, document)
+ }
+ DataInterchangeFileCSV: {
+ cartridges.put("xmlns:csv", "http://www.milyn.org/xsd/smooks/csv-1.2.xsd")
+ // set input type and active filename
+ pval = new ParameterValue
+ pval.value = "input.csv"
+ parameters.put("inputType", pval)
+ pval = new ParameterValue
+ pval.value = (dataInterchange.fileEndpoint as DataInterchangeFileCSV).fileURL
+ pval.modifiers.put("type", "input.type.actived")
+ parameters.put("input.csv", pval)
+ dataInterchange.generateImportConfig(fieldList, document, dataInterchange.fileEndpoint)
+ (dataInterchange.fileEndpoint as DataInterchangeFileCSV).input(dataInterchange, fieldList, document)
+ }
+ DataInterchangeFileEDI: {
+ cartridges.put("xmlns:edi", "http://www.milyn.org/xsd/smooks/edi-1.2.xsd")
+ // set input type and active filename
+ pval = new ParameterValue
+ pval.value = "input.edi"
+ parameters.put("inputType", pval)
+ pval = new ParameterValue
+ pval.value = (dataInterchange.fileEndpoint as DataInterchangeFileEDI).fileURL
+ pval.modifiers.put("type", "input.type.actived")
+ parameters.put("input.edi", pval)
+ dataInterchange.generateImportConfig(fieldList, document, dataInterchange.fileEndpoint)
+ (dataInterchange.fileEndpoint as DataInterchangeFileEDI).input(dataInterchange, document)
+ }
+ }
+ for(cdg:cartridges.keySet) {
+ document.documentElement.setAttributeNS("http://www.w3.org/2000/xmlns/", cdg, cartridges.get(cdg))
+ }
+ var params = document.createElement("params")
+ for(para:parameters.keySet) {
+ var pEl = document.createElement("param");
+ var name = document.createAttribute("name")
+ name.textContent = para
+ pEl.attributeNode = name
+ var value = document.createTextNode(parameters.get(para).value)
+ pEl.appendChild(value)
+ for(mod:parameters.get(para).modifiers.keySet) {
+ var pAt = document.createAttribute(mod)
+ pAt.textContent = parameters.get(para).modifiers.get(mod)
+ pEl.attributeNode = pAt
+ }
+ params.appendChild(pEl)
+ }
+ document.documentElement.appendChild(params)
+ var source = new DOMSource(document)
+ var res = new StringResult()
+ transformer.transform(source, res)
+ body = res.result
+ fsa.generateFile('''«dataInterchange.name»-«WorkerThreadRunnable.Direction.IMPORT.toString().toLowerCase()».xml''', DSLOutputConfigurationProvider.SMOOKS_OUTPUT_ONCE, body)
+ }
+
+ def input(DataInterchangeFileXML xml, DataInterchange interchange, Document doc) {
+ }
+
+ def input(DataInterchangeFileCSV csv, DataInterchange interchange, List<LEntityAttribute> fieldList, Document doc) {
+ var reader = doc.createElement("csv:reader")
+ var fields = doc.createAttribute("fields")
+ var fldList = <String>newArrayList
+ for(f:fieldList) {
+ fldList.add(f.toName)
+ }
+ fields.textContent = fldList.join(",")
+ reader.attributeNode = fields
+
+ if(csv.delimiter != null) {
+ var sep = doc.createAttribute("separator")
+ sep.textContent = csv.delimiter
+ reader.attributeNode = sep
+ }
+
+ if(csv.quoteCharacter != null) {
+ var quote = doc.createAttribute("quote")
+ quote.textContent = StringEscapeUtils.unescapeXml(csv.quoteCharacter)
+ reader.attributeNode = quote;
+ }
+
+ var indent = doc.createAttribute("indent")
+ indent.textContent = csv.indent.booleanValue.toString
+ reader.attributeNode = indent
+
+ var skip = doc.createAttribute("skipLines")
+ skip.textContent = csv.skipLines.toString
+ reader.attributeNode = skip
+
+ doc.documentElement.appendChild(reader)
+ }
+
+ def input(DataInterchangeFileEDI edi, DataInterchange interchange, Document doc) {
+ var reader = doc.createElement("edi:reader")
+ var mapping = doc.createAttribute("mappingModel")
+ mapping.textContent = edi.mappingModel
+ reader.attributeNode = mapping
+
+ var validate = doc.createAttribute("validate")
+ validate.textContent = edi.validate.booleanValue.toString
+ reader.attributeNode = validate
+
+ doc.documentElement.appendChild(reader)
+ }
+
+ def createFreemarker(Document doc, String templateString) {
+ var freemarker = doc.createElement("ftl:freemarker")
+ var apply = doc.createAttribute("applyOnElement")
+ apply.textContent = "#document"
+ freemarker.attributeNode = apply
+
+ doc.documentElement.appendChild(freemarker)
+ var template = doc.createElement("ftl:template")
+ var tplName = doc.createCDATASection(templateString.replaceAll("\r",""));
+ template.appendChild(tplName)
+ freemarker.appendChild(template)
+ }
+
+ def Element createBean(Document doc, String beanIdName, String className, String elementMap, boolean isList) {
+ var bean = doc.createElement("jb:bean")
+ doc.documentElement.appendChild(bean)
+ var beanId = doc.createAttribute("beanId")
+ beanId.textContent = beanIdName
+ bean.attributeNode = beanId
+ var clazz = doc.createAttribute("class")
+ clazz.textContent = '''«className»«IF isList»[]«ENDIF»'''
+ bean.attributeNode = clazz
+ // is mapping given?
+ if(elementMap != null) {
+ var create = doc.createAttribute("createOnElement")
+ create.textContent = elementMap
+ bean.attributeNode = create
+ }
+ return bean
+ }
+
+ def Element createProperty(Document doc, Element parent, String propertyName, String decoderName, EType type) {
+ var Element value = null
+ // try to find a value element, or create a new one
+ var node = parent.firstChild
+ while(node != null && (!node.nodeName.equals("jb:value") || !node.attributes.getNamedItem("property").nodeValue.equals(propertyName))) {
+ node = node.nextSibling
+ }
+ if(node == null) {
+ value = doc.createElement("jb:value")
+ parent.appendChild(value)
+ } else {
+ value = node as Element
+ }
+
+ var property = doc.createAttribute("property")
+ property.textContent = propertyName
+ value.attributeNode = property
+ if(decoderName != null) {
+ var decoder = doc.createAttribute("decoder")
+ decoder.textContent = decoderName
+ value.attributeNode = decoder
+ }
+ if (type == EType.DATE) {
+ var defaultValue = doc.createAttribute("default")
+ defaultValue.textContent = "null"
+ value.attributeNode = defaultValue
+ }
+ return value
+ }
+
+ def addMapping(Document doc, Element parent, String propertyName, String dataName) {
+ var elementMap = ""
+ var attr = parent.attributes.getNamedItem("createOnElement")
+ if (attr != null) {
+ elementMap = attr.textContent
+ }
+ var Element value = null
+ // try to find a value element, or create a new one
+ var node = parent.firstChild
+ while(node != null && node.hasAttributes && (!node.nodeName.equals("jb:value") || !node.attributes.getNamedItem("property").nodeValue.equals(propertyName))) {
+ node = node.nextSibling
+ }
+ if(node == null) {
+ value = doc.createElement("jb:value")
+ parent.appendChild(value)
+ } else {
+ value = node as Element
+ }
+ var data = doc.createAttribute("data")
+ data.textContent = elementMap+"/"+dataName
+ value.attributeNode = data
+ }
+
+ def Element createDecodeParam(Document doc, Element parent, String paramName, String paramValue) {
+ var param = doc.createElement("jb:decodeParam")
+ parent.appendChild(param)
+ var name = doc.createAttribute("name")
+ name.textContent = paramName
+ param.attributeNode = name
+ var form = doc.createTextNode(paramValue)
+ param.appendChild(form)
+ return param
+ }
+
+ def Element createWiring(Document doc, Element parent, String beanIdRefName, String propertyName, String setterName) {
+ var value = doc.createElement("jb:wiring")
+ parent.appendChild(value)
+ var beanIdRef = doc.createAttribute("beanIdRef")
+ beanIdRef.textContent = beanIdRefName
+ value.attributeNode = beanIdRef
+ if(propertyName != null) {
+ var property = doc.createAttribute("property")
+ property.textContent = propertyName
+ value.attributeNode = property
+ }
+ if(setterName != null) {
+ var setter = doc.createAttribute("setterMethod")
+ setter.textContent = setterName
+ value.attributeNode = setter
+ }
+ return value
+ }
+
+ def Element createExpression(Document doc, Element parent, String propertyName, String propertyValue) {
+ var expression = doc.createElement("jb:expression")
+ parent.appendChild(expression)
+ var property = doc.createAttribute("property")
+ property.textContent = propertyName
+ expression.attributeNode = property
+ var propNode = doc.createTextNode(propertyValue)
+ expression.appendChild(propNode)
+ return expression
+ }
+
+ def Element createDaoLocator(Document doc, Element parent, String beanIdName, String elementMap, boolean allowNoResult, boolean allowNonuniqueResult) {
+ var locator = doc.createElement("dao:locator")
+ if (parent == null) {
+ doc.documentElement.appendChild(locator)
+ } else {
+ parent.appendChild(locator)
+ }
+ var beanId = doc.createAttribute("beanId")
+ beanId.textContent = beanIdName
+ locator.attributeNode = beanId
+ // mapping given?
+ if(elementMap != null) {
+ var lookupOnElement = doc.createAttribute("lookupOnElement")
+ lookupOnElement.textContent = elementMap
+ locator.attributeNode = lookupOnElement
+ }
+
+ if(!allowNoResult) {
+ var onNoResult = doc.createAttribute("onNoResult")
+ onNoResult.textContent = "EXCEPTION"
+ locator.attributeNode = onNoResult
+ }
+ var uniqueResult = doc.createAttribute("uniqueResult")
+ uniqueResult.textContent = (!allowNonuniqueResult).booleanValue.toString
+ locator.attributeNode = uniqueResult
+ return locator
+ }
+
+ def Element createDaoQuery(Document doc, Element parent, String query) {
+ var daoQuery = doc.createElement("dao:query")
+ parent.appendChild(daoQuery)
+ var queryText = doc.createTextNode(query)
+ daoQuery.appendChild(queryText)
+ return daoQuery
+ }
+
+ def Element createDaoParam(Document doc, Element parent, String paramName, String paramValue, String elementMap, String dataMap) {
+ var Element daoParams = null
+ var node = parent.firstChild
+ while(node != null && !node.nodeName.equals("dao:params")) {
+ node = node.nextSibling
+ }
+ if(node == null) {
+ daoParams = doc.createElement("dao:params")
+ parent.appendChild(daoParams)
+ } else {
+ daoParams = node as Element
+ }
+ var daoValue = doc.createElement("dao:value")
+ daoParams.appendChild(daoValue)
+ var param = doc.createAttribute("name")
+ param.textContent = paramName
+ daoValue.attributeNode = param
+ var decoder = doc.createAttribute("decoder")
+ decoder.textContent = paramValue
+ daoValue.attributeNode = decoder
+ // mapping given?
+ if(dataMap != null) {
+ var data = doc.createAttribute("data")
+ data.textContent = elementMap+"/"+dataMap
+ daoValue.attributeNode = data
+ }
+ return daoParams
+ }
+
+ def generateExportConfig(DataInterchange dataInterchange, Document doc, DataInterchangeFile endPoint, String delimiter, String quote) {
+ var substitutionMap = <String,String>newHashMap
+ var substitutionCount = 0
+ var fieldList = <LEntityAttribute>newArrayList
+ var String rootEntityName = null
+ var Document ftlDocument = null
+ var Element bean = null
+ var vector = "vector"
+ for(path : dataInterchange.path) {
+ if (rootEntityName == null) {
+ rootEntityName = path.entity.name.toString
+ }
+ if (dataInterchange.fileEndpoint instanceof DataInterchangeFileXML) {
+ var currentKey = '''list«substitutionCount»'''
+ if(ftlDocument == null) {
+ ftlDocument = domImpl.createDocument(null, "vector", null)
+ }
+ substitutionMap.put(currentKey, '''«vector» as «path.entity.name»''')
+ bean = createXmlBean(ftlDocument, bean, path.entity, path.format, currentKey)
+ substitutionCount = substitutionCount + 1
+ }
+ for (f : path.entity.features) {
+ if(f instanceof LAttribute && !f.toMany) {
+ if ((!"disposed".equals((f as LEntityFeature).toName) && (!"id".equals((f as LEntityFeature).toName)))) {
+ fieldList.add(f as LEntityAttribute)
+ }
+ }
+ if(f instanceof LReference && f.toMany) {
+ var iter = dataInterchange.path.iterator
+ var next = iter.next
+ // find this entity
+ while (iter.hasNext && !next.entity.toName.equals(path.entity.toName)) {
+ next = iter.next
+ }
+ while (iter.hasNext) {
+ // move to next entity
+ next = iter.next
+ if (next != null && next.entity.toName.equals((f.type as LEntity).toName)) {
+ vector = '''«path.entity.name».«(f as LEntityFeature).name»'''
+ }
+ }
+ }
+ }
+ }
+ if(endPoint instanceof DataInterchangeFileCSV) {
+ createFreemarker(doc, createCsvTemplate(rootEntityName, fieldList, delimiter, quote, dataInterchange.path))
+ }
+ if(endPoint instanceof DataInterchangeFileXML) {
+ createFreemarker(doc, createXmlTemplate(ftlDocument, substitutionMap))
+ }
+ }
+
+ def generateImportConfig(DataInterchange dataInterchange, List<LEntityAttribute> fieldList, Document doc, DataInterchangeFile endPoint) {
+ var autoMapping = ""
+ if(endPoint instanceof DataInterchangeFileCSV) {
+ autoMapping = "/csv-set"
+ } else if(endPoint instanceof DataInterchangeFileXML) {
+ autoMapping = "vector"
+ }
+ for(path : dataInterchange.path) {
+ var map = ""
+ if(path.elementMap == null) {
+ map = autoMapping
+ } else {
+ map = path.elementMap
+ }
+ var Element bean = null
+ if(path.recordList) {
+ var rootBean = createBean(doc, path.entity.toName+"List", path.entity.fullyQualifiedName.toString, map, true)
+ createWiring(doc, rootBean, path.entity.toName, null, null)
+ if(endPoint instanceof DataInterchangeFileCSV) {
+ autoMapping = autoMapping + "/csv-record"
+ } else if(endPoint instanceof DataInterchangeFileXML) {
+ autoMapping = autoMapping + "/" + path.entity.toName
+ }
+ if(path.elementMap == null) {
+ map = autoMapping
+ } else {
+ map = path.elementMap
+ }
+ bean = createBean(doc, path.entity.toName, path.entity.fullyQualifiedName.toString, map, false)
+ } else {
+ if(endPoint instanceof DataInterchangeFileXML) {
+ autoMapping = autoMapping + "/" + path.entity.toName
+ }
+ if(path.elementMap == null) {
+ map = autoMapping
+ } else {
+ map = path.elementMap
+ }
+ bean = createBean(doc, path.entity.toName, path.entity.fullyQualifiedName.toString, map, false)
+ }
+ var mappingFound = false
+ for (f : path.entity.features) {
+ switch f {
+ LAttribute: {
+ if (!f.toMany) {
+ // enable mapping for this field, but first try special cases...
+ if ((!"disposed".equals((f as LEntityFeature).toName) && (!"id".equals((f as LEntityFeature).toName) && (!path.markLatest || !path.latestProperty.toName.equals((f as LEntityFeature).toName))))) {
+ // add to the level's field list
+ if (path.recordList || path.recordElement) {
+ fieldList.add(f as LEntityAttribute)
+ }
+ var expressionFound = false
+ // scan expressions for this field
+ for (expr : path.expression) {
+ switch(expr) {
+ DataInterchangeEntityExpression: {
+ // is there an entity expression for this attribute ?
+ if ((f as LEntityFeature).toName.equals((expr as DataInterchangeEntityExpression).targetProperty.toName)) {
+ createExpression(doc, bean, (f as LEntityFeature).toName, (expr as DataInterchangeEntityExpression).entity.toName+"."+(expr as DataInterchangeEntityExpression).property.toName)
+ expressionFound = true
+ }
+ }
+ DataInterchangePredefinedExpression: {
+ // is there an predefined expression modeled for this attribute ?
+ if ((f as LEntityFeature).toName.equals((expr as DataInterchangePredefinedExpression).targetProperty.toName)) {
+ if("UUID".equals((expr as DataInterchangePredefinedExpression).bean.literal)) {
+ createExpression(doc, bean, (f as LEntityFeature).toName, "PUUID."+(expr as DataInterchangePredefinedExpression).beanType.getName)
+ } else {
+ createExpression(doc, bean, (f as LEntityFeature).toName, "PTIME."+(expr as DataInterchangePredefinedExpression).bean.getName+(expr as DataInterchangePredefinedExpression).beanType.getName)
+ }
+ expressionFound = true
+ }
+ }
+ }
+ }
+ // scan formats for this field
+ var formatFound = false
+ for (format : path.format) {
+ // is there a format modeled for this attribute ?
+ if ((f as LEntityFeature).toName.equals(format.targetProperty.toName)) {
+ var value = createProperty(doc, bean, (f as LEntityFeature).toName, (f as LEntityFeature).decoder, dtType.getBasicType(f as LEntityAttribute))
+ if(format.format != null) {
+ createDecodeParam(doc, value, "format", format.format)
+ if (format.locale != null) {
+ createDecodeParam(doc, value, "locale-language", format.locale.split("_").get(0))
+ if(format.locale.split("_").size > 1) {
+ createDecodeParam(doc, value, "locale-country", format.locale.split("_").get(1))
+ }
+ }
+ }
+ formatFound = true
+ }
+ }
+ // scan lookup for this field - import only
+ var lookupFound = false
+ for (lookup : path.lookup) {
+ // entity and property must match
+ if ((f as LEntityFeature).toName.equals(lookup.targetProperty.toName)) {
+ var value = createWiring(doc, bean, (f.type as LEntity).toName, (f as LReference).name, null)
+ var locator = createDaoLocator(doc, value, (f.type as LEntity).toName, lookup.elementMap, lookup.allowNoResult, lookup.allowNonuniqueResult)
+ var daoQuery = createDaoQuery(doc, locator, (f.type as LEntity).query(lookup))
+ createDaoParam(doc, daoQuery, "param", (f as LEntityFeature).type.name.toFirstUpper, lookup.elementMap, lookup.dataMap)
+ }
+ }
+ // default for mapping purposes
+ if (!expressionFound && !formatFound && !lookupFound) {
+ // add format decoder
+ var etype = dtType.getBasicType(f as LEntityAttribute)
+ var value = createProperty(doc, bean, (f as LEntityFeature).toName, (f as LEntityFeature).decoder, etype)
+ if (etype == EType.DATE) {
+ createDecodeParam(doc, value, "format", "yyyy-MM-dd")
+ }
+ }
+ // if mapping given
+ for(mapping : path.mappings) {
+ if(f.name.equals(mapping.property.name)) {
+ addMapping(doc, bean, (f as LEntityFeature).toName, mapping.data)
+ mappingFound = true
+ }
+ }
+ // if recordElement given
+ if (!mappingFound && !fieldList.isEmpty) {
+ if (path.recordList || path.recordElement) {
+ for(fld : fieldList) {
+ addMapping(doc, bean, fld.toName, fld.toName)
+ }
+ }
+ }
+ // default mapping for xml
+ if (!mappingFound && endPoint instanceof DataInterchangeFileXML) {
+ addMapping(doc, bean, (f as LEntityFeature).toName, (f as LEntityFeature).toName)
+ }
+ }
+ }
+ }
+ // check relations for modeled lookup
+ LReference: {
+ if (f.toMany) {
+ // one to many
+ // mapped automatically
+ var iter = dataInterchange.path.iterator
+ var next = iter.next
+ // find this entity
+ while (iter.hasNext && !next.entity.toName.equals(path.entity.toName)) {
+ next = iter.next
+ }
+ while (iter.hasNext) {
+ // move to next entity
+ next = iter.next
+ if (next != null && next.entity.toName.equals((f.type as LEntity).toName)) {
+ createWiring(doc, bean, (f.type as LEntity).toName, null, (f as LEntityFeature).toAdder((f as LEntityFeature).name).simpleName)
+ }
+ }
+ } else {
+ // many to one
+ // generate possible lookups for this many to one relationship
+ for (lookup : path.lookup) {
+ // entity and property must match
+ if (lookup.targetProperty.toName.equals((f as LReference).name)) {
+ createWiring(doc, bean, (f.type as LEntity).toName, (f as LReference).name, null)
+ var locator = createDaoLocator(doc, null, (f.type as LEntity).toName, lookup.elementMap, lookup.allowNoResult, lookup.allowNonuniqueResult)
+ createDaoQuery(doc, locator, (f.type as LEntity).query(lookup))
+ createDaoParam(doc, locator, "param", lookup.queryProperty.type.name.toFirstUpper, lookup.elementMap, lookup.dataMap)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ def Element createXmlBean(Document doc, Element parent, LEntity entity, EList<DataInterchangeFormat> formats, String currentKey) {
+ var bean = doc.createElement(entity.name)
+ var pi = doc.createProcessingInstruction(currentKey, "")
+ if(parent == null) {
+ doc.documentElement.appendChild(pi)
+ doc.documentElement.appendChild(bean)
+ } else {
+ bean = doc.createElement(entity.name)
+ parent.appendChild(pi)
+ parent.appendChild(bean)
+ }
+ for(p:entity.allAttributes) {
+ if ((!"disposed".equals(p.toName) && (!"id".equals(p.toName)))) {
+ var format = null as DataInterchangeFormat
+ for (step : formats) {
+ // is there a format modeled for this attribute ?
+ if ((p as LEntityFeature).toName.equals(step.targetProperty.toName)) {
+ if (step.format != null) {
+ format = step
+ }
+ }
+ }
+ var property = doc.createElement(p.toName)
+ property.textContent = encodeFreemarker(entity.name, p, format, "")
+ bean.appendChild(property)
+ }
+ }
+ var pa = doc.createProcessingInstruction(currentKey, "")
+ if(parent == null) {
+ doc.documentElement.appendChild(pa)
+ } else {
+ parent.appendChild(pa)
+ }
+ return bean
+ }
+
+ def String decoder(LEntityFeature f) {
+ return getPrimitiveDataTypeName(f as LEntityAttribute)
+ }
+
+ def String getPrimitiveDataTypeName(LEntityAttribute attribute) {
+ var eType = dtType.getBasicType(attribute)
+ var String typeName = null
+ if (eType == EType.DATE) {
+ typeName = "Date"
+ }
+ else if (attribute.type != null && (attribute.type instanceof LDataType) && (attribute.type as LDataType).jvmTypeReference != null) {
+ typeName = (attribute.type as LDataType).jvmTypeReference.simpleName
+ } else {
+ typeName = attribute.type.name
+ }
+ if ("int".equals(typeName)) {
+ typeName = "Integer"
+ }
+ return typeName.toFirstUpper
+ }
+// <ftl:freemarker applyOnElement="org.eclipse.osbp.foodmart.entities.Mregion">
+// <ftl:template>
+// <!--<#list vector as Mregion>
+//<Mregion>
+// <sales_city>${Mregion.sales_city}</sales_city>
+// <#list Mregion.stores as Mstore>
+// <store_type>${Mstore.store_type}</store_type>
+// </#list>
+//</Mregion>
+//</#list>
+//-->
+// </ftl:template>
+// </ftl:freemarker>
+
+ def String createXmlTemplate(Document doc, HashMap<String,String> substitutionMap) {
+ var source = new DOMSource(doc)
+ var res = new StringResult()
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ transformer.transform(source, res)
+ var output = res.result
+ // processing instructions are embedded in question marks - they must be replaced
+ for(l:substitutionMap.keySet) {
+ output = output.replaceFirst(l, '''#list «substitutionMap.get(l)»''')
+ }
+ for(l:substitutionMap.keySet) {
+ output = output.replaceFirst(l, '''/#list''')
+ }
+ return output.replace("&lt;","<").replace("&gt;",">").replace("<?","<").replace("?>",">")//.replace("</#","\n</#")
+ }
+
+ def String createCsvTemplate(String rootEntityName, List<LEntityAttribute> fieldList, String delimiter, String quote, EList<DataInterchangeBean> paths) {
+ var tmpList = <String>newArrayList()
+ var fldList = <String>newArrayList
+ for(field:fieldList) {
+ tmpList.add(encodeFreemarker(rootEntityName, field, paths, quote))
+ fldList.add(field.toName)
+ }
+ var body = '''«fldList.join(delimiter)»
+<#list vector as «rootEntityName»>
+«tmpList.join(delimiter)»
+</#list>'''
+ return body
+ }
+
+ def String encodeFreemarker(String entityName, LEntityAttribute field, EList<DataInterchangeBean> paths, String quote) {
+ var format = null as DataInterchangeFormat
+ val entity = field.eContainer as LEntity
+ for (path : paths) {
+ if (path.entity.equals(entity)) {
+ for (step : path.format) {
+ // is there a format modeled for this attribute ?
+ if (field.toName.equals(step.targetProperty.toName)) {
+ if (step.format != null) {
+ format = step
+ }
+ }
+ }
+ }
+ }
+ return encodeFreemarker(entityName, field, format, quote)
+ }
+
+ def String encodeFreemarker(String entityName, LEntityAttribute field, DataInterchangeFormat format, String quote) {
+ var etype = dtType.getBasicType(field)
+ if (etype == EType.BOOLEAN) {
+ return '''${(«entityName».«field.toName»?c)!}'''
+ }
+ else if (format != null) {
+ return '''${(«entityName».«field.toName»?string["«format.format»"])!}'''
+ }
+ else if (etype == EType.DATE) {
+ return '''${(«entityName».«field.toName»?date)!}'''
+ }
+ else if (etype == EType.STRING) {
+ return '''«quote»${(«entityName».«field.toName»)!}«quote»'''
+ }
+ else {
+ return '''${(«entityName».«field.toName»)!}'''
+ }
+ }
+
+ /* create a multistage left joined query to climb up along the one to many relations until import marker */
+ def String query(LEntity entity, DataInterchangeLookup lookup) {
+ var aliasCnt = 0
+ var select = '''«entity.toName» x«aliasCnt»'''
+ var joinList = <String>newArrayList
+ var whereList = <String>newArrayList
+ var qstr = '''x«aliasCnt».«lookup.queryProperty.toName» = :param'''
+ whereList.add(qstr)
+ if (lookup.markerPath != null) {
+ for(markerEntity:lookup.markerPath.path) {
+ aliasCnt = aliasCnt + 1
+ if (markerEntity.markLatest) {
+ qstr = '''x«aliasCnt».«markerEntity.markerProperty.toName» = 1'''
+ whereList.add(qstr)
+ }
+ for(ff:entity.features) {
+ if (ff instanceof LReference && !ff.toMany) {
+ if (markerEntity.markerEntity.toName.equals((ff.type as LEntity).toName)) {
+ qstr = '''x«aliasCnt-1».«ff.toName» x«aliasCnt»'''
+ joinList.add(qstr)
+ }
+ }
+ }
+ }
+ }
+ return '''from «select»«IF joinList.size>0» left join «ENDIF»«joinList.join(" left join ")» where «whereList.join(" and ")»'''
+ }
+
+ override createAppendable(EObject context, ImportManager importManager, GeneratorConfig config) {
+ // required to initialize the needed builder to avoid deprecated methods
+ builder = context.eResource
+ // ---------
+ addImportFor(importManager, _typeReferenceBuilder
+ , FrameworkUtil
+ , SmooksOSGIFactory
+ , SmooksFactory
+ , Smooks
+ , HtmlReportGenerator
+ , ExecutionContext
+ , JavaResult
+ , XMLBinding
+ , StreamSource
+ , ByteArrayInputStream
+ , URL
+ , URI
+ , InputStream
+ , StreamUtils
+ , MalformedURLException
+ , IOException
+ , FileAlreadyExistsException
+ , URISyntaxException
+ , EntityManager
+ , PersistenceUtil
+ , EntityManagerRegister
+ , EntityTransaction
+ , Logger
+ , LoggerFactory
+ , Label
+ , Button
+ , NativeButton
+ , ClickListener
+ , ClickEvent
+ , ContentMode
+ , PersistenceUnitProperties
+ , HorizontalLayout
+ , ProgressBar
+ , IEventBroker
+ , WorkerThreadRunnable
+ , HashMap
+ , Executors
+ , TimeUnit
+ , QueryHints
+ , PessimisticLock
+ , MissingResourceException
+ , MessageFormat
+ , EventHandler
+ , Event
+ , EventUtils
+ , EventBrokerMsg
+ , Bundle
+ , BundleContext
+ , List
+ , Arrays
+ , StringWriter
+ , StringReader
+ , OutputKeys
+ , StreamResult
+ , JavaSource
+ , CriteriaBuilder
+ , CriteriaQuery
+ , Root
+ , TypedQuery
+ , JoinType
+ , Paths
+ , Path
+ , Files
+ , StandardOpenOption
+ , BufferedOutputStream
+ , FilterLifecycleEvent
+ , ElementPresentEvent
+ , EventType
+ , UI
+ , Pair
+ , IEntityImportInitializationListener
+ , ConstraintViolationException
+ , ConstraintViolation
+ )
+ super.createAppendable(context, importManager, config)
+ }
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/scoping/DataDSLScopeProvider.xtend b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/scoping/DataDSLScopeProvider.xtend
new file mode 100644
index 0000000..796c5fb
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/scoping/DataDSLScopeProvider.xtend
@@ -0,0 +1,233 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ *
+ * This copyright notice shows up in the generated Java code
+ *
+ */
+
+package org.eclipse.osbp.xtext.datainterchange.scoping
+
+import org.eclipse.osbp.xtext.datainterchange.DataDSLPackage
+import org.eclipse.osbp.xtext.datainterchange.DataInterchange
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeBean
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeEntityExpression
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookup
+import org.eclipse.osbp.xtext.datainterchange.DataInterchangeMarkerEntity
+import javax.inject.Inject
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.EReference
+import org.eclipse.xtext.resource.EObjectDescription
+import org.eclipse.xtext.resource.IEObjectDescription
+import org.eclipse.xtext.scoping.IScope
+import org.eclipse.xtext.scoping.impl.MapBasedScope
+import org.eclipse.xtext.xbase.annotations.typesystem.XbaseWithAnnotationsBatchScopeProvider
+import org.eclipse.osbp.dsl.entity.xtext.extensions.EntityTypesBuilder
+import org.eclipse.osbp.dsl.entity.xtext.extensions.ModelExtensions
+import org.eclipse.osbp.dsl.semantic.common.types.LAttribute
+import org.eclipse.osbp.dsl.semantic.common.types.LReference
+import org.eclipse.osbp.dsl.semantic.entity.LEntity
+import org.eclipse.osbp.dsl.semantic.entity.LEntityReference
+
+class DataDSLScopeProvider extends XbaseWithAnnotationsBatchScopeProvider {
+ @Inject extension ModelExtensions
+ @Inject extension EntityTypesBuilder
+
+ override getScope(EObject context, EReference reference) {
+ if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_BEAN__LATEST_PROPERTY) {
+ return getScope_Data_Entity_latest(context, reference)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_EXPRESSION__TARGET_PROPERTY) {
+ return getScope_Data_Target_property(context, reference, true)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_FORMAT__TARGET_PROPERTY) {
+ return getScope_Data_Target_property(context, reference, true)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_ENTITY_EXPRESSION__ENTITY) {
+ return getScope_Data_Expression_entity(context, reference, true)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_ENTITY_EXPRESSION__PROPERTY) {
+ return getScope_Data_Expression_entity(context, reference, false)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_LOOKUP__TARGET_PROPERTY) {
+ return getScope_Data_Target_property(context, reference, false)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_LOOKUP__QUERY_PROPERTY) {
+ return getScope_Data_Lookup_queryProperty(context, reference)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_LOOKUP__ENTITY) {
+ return getScope_Data_Lookup_lookupEntity(context, reference)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_BEAN__ENTITY) {
+ return getScope_Data_Bean_Entity(context, reference)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_MAPPING__PROPERTY) {
+ return getScope_Data_Target_property(context, reference, true)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_MARKER_ENTITY__MARKER_ENTITY) {
+ return getScope_Data_Markerpath_entity(context, reference)
+ } else if (reference == DataDSLPackage.Literals.DATA_INTERCHANGE_MARKER_ENTITY__MARKER_PROPERTY) {
+ return getScope_Data_Entity_latest(context, reference)
+ } else {
+ super.getScope(context, reference)
+ }
+ }
+
+ def getScope_Data_Bean_Entity(EObject context, EReference reference) {
+ var result = <IEObjectDescription>newArrayList
+ var eObj = context.eContainer
+ while (!(eObj instanceof DataInterchange)) {
+ eObj = eObj.eContainer
+ }
+ if (eObj != null) {
+ var DataInterchangeBean previousEntity = null
+ for(diEntity:(eObj as DataInterchange).path) {
+ // find me
+ if (previousEntity != null) {
+ // remove this entity from result, we already used it
+ var IEObjectDescription delObj = null
+ for(r:result) {
+ if (r.name.toString.equals(previousEntity.entity.name)) {
+ delObj = r
+ }
+ }
+ if(delObj != null) {
+ result.remove(delObj)
+ }
+ // scoping refers to the previous owner
+ for(f:previousEntity.entity.features) {
+ if (f instanceof LReference) {
+ if (f.cascading && f.toMany) {
+ var ref = (f as LEntityReference)
+ result.add(EObjectDescription.create(ref.type.toName, ref.type))
+ }
+ }
+ }
+ }
+ if (!diEntity.equals(context)) {
+ previousEntity = diEntity
+ }
+ else if (previousEntity == null) {
+ return super.getScope(context, reference)
+ }
+ }
+ }
+ return MapBasedScope.createScope(IScope.NULLSCOPE, result)
+ }
+
+ def getScope_Data_Lookup_queryProperty(EObject context, EReference reference) {
+ var result = <IEObjectDescription>newArrayList
+ if (context != null && context instanceof DataInterchangeLookup) {
+ var entity = (context as DataInterchangeLookup).entity
+ for (prop : entity.features) {
+ if (prop instanceof LAttribute && !prop.toMany) {
+ result.add(EObjectDescription.create((prop as LAttribute).name, (prop as LAttribute)))
+ }
+ }
+ }
+ return MapBasedScope.createScope(IScope.NULLSCOPE, result)
+ }
+
+ def getScope_Data_Lookup_lookupEntity(EObject context, EReference reference) {
+ var result = <IEObjectDescription>newArrayList
+ var targetProperty = (context as DataInterchangeLookup).targetProperty
+ var eObj = context.eContainer
+ while (!(eObj instanceof DataInterchangeBean)) {
+ eObj = eObj.eContainer
+ }
+ if (eObj != null) {
+ var entity = (eObj as DataInterchangeBean).entity
+ for (prop : entity.features) {
+ if (prop instanceof LReference && !prop.toMany && (prop as LReference).name.equals(targetProperty.toName)) {
+ result.add(EObjectDescription.create((prop as LReference).type.name, (prop as LReference).type))
+ }
+ }
+ }
+ return MapBasedScope.createScope(IScope.NULLSCOPE, result)
+ }
+
+ def getScope_Data_Expression_entity(EObject context, EReference reference, boolean filterEntity) {
+ var result = <IEObjectDescription>newArrayList
+ var targetProperty = (context as DataInterchangeEntityExpression).targetProperty
+ var fromEntity = (context as DataInterchangeEntityExpression).entity
+ var eObj = context.eContainer
+ while (!(eObj instanceof DataInterchange)) {
+ eObj = eObj.eContainer
+ }
+ if (eObj != null) {
+ for (path : (eObj as DataInterchange).path) {
+ for (f:path.entity.features) {
+ if (f instanceof LAttribute && (f as LAttribute).type.name.equals(targetProperty.type.name)) {
+ if (filterEntity) {
+ result.add(EObjectDescription.create(path.entity.toName, path.entity))
+ } else if (fromEntity == null || path.entity.toName.equals(fromEntity.toName)) {
+ result.add(EObjectDescription.create((f as LAttribute).toName, (f as LAttribute)))
+ }
+ }
+ }
+ }
+ }
+ return MapBasedScope.createScope(IScope.NULLSCOPE, result)
+ }
+
+ def getScope_Data_Target_property(EObject context, EReference reference, boolean filterAttributes) {
+ var result = <IEObjectDescription>newArrayList
+ var eObj = context.eContainer
+ while (!(eObj instanceof DataInterchangeBean)) {
+ eObj = eObj.eContainer
+ }
+ if (eObj != null) {
+ var entity = (eObj as DataInterchangeBean).entity
+ var marker = (eObj as DataInterchangeBean).latestProperty
+ for (prop : entity.features) {
+ if (filterAttributes) {
+ if (prop instanceof LAttribute && (marker==null || !prop.toName.equals(marker.toName))) {
+ result.add(EObjectDescription.create((prop as LAttribute).name, (prop as LAttribute)))
+ }
+ } else {
+ if (prop instanceof LReference && !prop.toMany) {
+ result.add(EObjectDescription.create((prop as LReference).name, (prop as LReference)))
+ }
+ }
+ }
+ }
+ return MapBasedScope.createScope(IScope.NULLSCOPE, result)
+ }
+
+ def getScope_Data_Entity_latest(EObject context, EReference reference) {
+ var result = <IEObjectDescription>newArrayList
+ var LEntity rootEntity = null
+ if (context != null) {
+ switch context {
+ DataInterchangeBean: {
+ rootEntity = (context as DataInterchangeBean).entity
+ }
+ DataInterchangeMarkerEntity: {
+ rootEntity = (context as DataInterchangeMarkerEntity).markerEntity
+ }
+ }
+ for (prop : rootEntity.features) {
+ if (prop instanceof LAttribute && "boolean".equals((prop as LAttribute).type.name)) {
+ result.add(EObjectDescription.create((prop as LAttribute).name, (prop as LAttribute)))
+ }
+ }
+ }
+ return MapBasedScope.createScope(IScope.NULLSCOPE, result)
+ }
+
+ def getScope_Data_Markerpath_entity(EObject context, EReference reference) {
+ var result = <IEObjectDescription>newArrayList
+ var eObj = context.eContainer
+ while (!(eObj instanceof DataInterchangeLookup)) {
+ eObj = eObj.eContainer
+ }
+ if (eObj != null) {
+ var entity = (eObj as DataInterchangeLookup).entity
+ for (f:entity.references) {
+ if (!f.toMany) {
+ result.add(EObjectDescription.create(f.type.toName , f.type))
+ }
+ }
+ }
+ return MapBasedScope.createScope(IScope.NULLSCOPE, result)
+ }
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/validation/DataDSLValidator.xtend b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/validation/DataDSLValidator.xtend
new file mode 100644
index 0000000..c447636
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/validation/DataDSLValidator.xtend
@@ -0,0 +1,38 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ *
+ * This copyright notice shows up in the generated Java code
+ *
+ */
+
+package org.eclipse.osbp.xtext.datainterchange.validation
+//import org.eclipse.xtext.validation.Check
+
+/**
+ * Custom validation rules.
+ *
+ * see http://www.eclipse.org/Xtext/documentation.html#validation
+ */
+class DataDSLValidator extends AbstractDataDSLValidator {
+
+// public static val INVALID_NAME = 'invalidName'
+//
+// @Check
+// def checkGreetingStartsWithCapital(Greeting greeting) {
+// if (!Character.isUpperCase(greeting.name.charAt(0))) {
+// warning('Name should start with a capital',
+// MyDslPackage.Literals.GREETING__NAME,
+// INVALID_NAME)
+// }
+// }
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/valueconverter/DataDSLQualifiedNameProvider.java b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/valueconverter/DataDSLQualifiedNameProvider.java
new file mode 100644
index 0000000..a38751d
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/valueconverter/DataDSLQualifiedNameProvider.java
@@ -0,0 +1,36 @@
+/**
+ *
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
+ *
+ */
+ package org.eclipse.osbp.xtext.datainterchange.valueconverter;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.xbase.scoping.XbaseQualifiedNameProvider;
+
+import com.google.inject.Inject;
+
+@SuppressWarnings("restriction")
+public class DataDSLQualifiedNameProvider extends XbaseQualifiedNameProvider {
+
+ @Inject
+ private IQualifiedNameConverter qualifiedNameConverter;
+
+ @Override
+ public QualifiedName getFullyQualifiedName(EObject obj) {
+ if (obj == null) {
+ return QualifiedName.create("");
+ }
+ return super.getFullyQualifiedName(obj);
+ }
+}
diff --git a/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/valueconverter/DataDSLValueConverterService.java b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/valueconverter/DataDSLValueConverterService.java
new file mode 100644
index 0000000..4020c30
--- /dev/null
+++ b/org.eclipse.osbp.xtext.datainterchange/src/org/eclipse/osbp/xtext/datainterchange/valueconverter/DataDSLValueConverterService.java
@@ -0,0 +1,41 @@
+/**
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christophe Loetz - Initial implementation
+ */
+package org.eclipse.osbp.xtext.datainterchange.valueconverter;
+
+import org.eclipse.osbp.xtext.basic.valueconverter.TRANSLATABLESTRINGValueConverter;
+import org.eclipse.xtext.conversion.IValueConverter;
+import org.eclipse.xtext.conversion.ValueConverter;
+import org.eclipse.xtext.xbase.conversion.XbaseValueConverterService;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * Adds a value conversion for the QualifiedNameWithWildCard rule.
+ *
+ */
+@SuppressWarnings("restriction")
+@Singleton
+public class DataDSLValueConverterService extends XbaseValueConverterService {
+ @Inject
+ private TRANSLATABLESTRINGValueConverter converter;
+
+ @ValueConverter(rule = "QualifiedNameWithWildCard")
+ public IValueConverter<String> getQualifiedNameWithWildCard() {
+ return getQualifiedNameValueConverter();
+ }
+
+ @ValueConverter(rule = "TRANSLATABLESTRING")
+ public IValueConverter<String> getTranslatableStringValueConverter() {
+ return converter;
+ }
+
+}

Back to the top