| /** |
| * |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| * |
| * |
| * This copyright notice shows up in the generated Java code |
| * |
| */ |
| |
| package org.eclipse.osbp.xtext.datainterchange.jvmmodel |
| |
| import com.vaadin.ui.Button |
| import com.vaadin.ui.CssLayout |
| import com.vaadin.ui.Label |
| import com.vaadin.ui.Panel |
| import com.vaadin.ui.VerticalLayout |
| import java.io.OutputStream |
| import java.net.URL |
| import java.nio.file.Path |
| import java.util.ArrayList |
| import java.util.HashMap |
| 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.ui.di.Focus |
| import org.eclipse.e4.ui.model.application.MApplication |
| import org.eclipse.osbp.core.api.persistence.IPersistenceService |
| import org.eclipse.osbp.datainterchange.api.IDataInterchange |
| 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.runtime.common.event.EventDispatcherEvent |
| import org.eclipse.osbp.runtime.common.event.IEventDispatcher |
| import org.eclipse.osbp.ui.api.customfields.IBlobService |
| import org.eclipse.osbp.ui.api.e4.IE4Focusable |
| import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService |
| import org.eclipse.osbp.ui.api.user.IUser |
| import org.eclipse.osbp.xtext.datainterchange.DataInterchange |
| import org.eclipse.osbp.xtext.datainterchange.DataInterchangeBean |
| import org.eclipse.osbp.xtext.datainterchange.DataInterchangeBlobMapping |
| import org.eclipse.osbp.xtext.datainterchange.DataInterchangeExportFilter |
| 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.DataInterchangeFilterCondition |
| import org.eclipse.osbp.xtext.datainterchange.DataInterchangeGroup |
| import org.eclipse.osbp.xtext.datainterchange.DataInterchangePackage |
| import org.eclipse.osbp.xtext.datainterchange.EntityManagerMode |
| import org.eclipse.osbp.xtext.datainterchange.common.WorkerThreadRunnable |
| import org.eclipse.osbp.xtext.datainterchange.common.WorkerThreadRunnable.Direction |
| import org.eclipse.osbp.xtext.entitymock.common.IEntityImportInitializationListener |
| 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.osgi.framework.BundleEvent |
| import org.osgi.framework.BundleListener |
| 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. |
| * </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 group |
| * An instance of {@link DataInterchangeGroup} |
| * @param acceptor |
| * the xtext acceptor interface |
| * @param isPreIndexingPhase |
| * true if in preindexing phase |
| */ |
| def dispatch void infer(DataInterchangeGroup group, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) { |
| (group.eContainer as DataInterchangePackage).generatePckgName(acceptor) |
| // create a view |
| var cls = group.toClass(group.name + "TriggerView"); |
| cls.simpleName = cls.simpleName.toFirstUpper |
| acceptor.accept(cls, |
| [ |
| superTypes += _typeReferenceBuilder.typeRef(AbstractHybridVaaclipseView) |
| superTypes += _typeReferenceBuilder.typeRef(BundleListener) |
| superTypes += _typeReferenceBuilder.typeRef(IUser.UserLocaleListener) |
| superTypes += _typeReferenceBuilder.typeRef(IEventDispatcher.Receiver) |
| superTypes += _typeReferenceBuilder.typeRef(IE4Focusable) |
| packageName = DataDSLModelGenerator.pckgName |
| it.fileHeader = group.documentation |
| it.toFields(group) |
| it.toConstructor(group) |
| it.toOperations(group) |
| ]) |
| |
| // create classes |
| group.datInts.forEach[dataInterchange| |
| var clsName2 = DataDSLModelGenerator.pckgName+"."+dataInterchange.name |
| acceptor.accept(dataInterchange.toClass(clsName2), |
| [ |
| superTypes += _typeReferenceBuilder.typeRef(WorkerThreadRunnable) |
| annotations += _annotationTypesBuilder.annotationRef(SuppressWarnings, "serial") |
| packageName = DataDSLModelGenerator.pckgName |
| it.fileHeader = group.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, DataInterchangeGroup group) { |
| var JvmField field = null |
| field = group.toField("sidebar", _typeReferenceBuilder.typeRef(VerticalLayout)) |
| type.members += field |
| field = group.toField("log", _typeReferenceBuilder.typeRef(Logger)) [setInitializer([ append('''LoggerFactory.getLogger(«group.fullyQualifiedName.lastSegment.toFirstUpper»TriggerView.class)''') ])] |
| field.final = true |
| field.static = true |
| type.members += field |
| field = group.toField("menu", _typeReferenceBuilder.typeRef(CssLayout)) |
| type.members += field |
| field = group.toField("menuPanel", _typeReferenceBuilder.typeRef(Panel)) |
| type.members += field |
| field = group.toField("branding", _typeReferenceBuilder.typeRef(CssLayout)) |
| type.members += field |
| field = group.toField("persistenceService", _typeReferenceBuilder.typeRef(IPersistenceService)) [ |
| annotations += _annotationTypesBuilder.annotationRef(Inject) |
| ] |
| type.members += field |
| field = group.toField("progressBars", _typeReferenceBuilder.typeRef(Map, _typeReferenceBuilder.typeRef(String), _typeReferenceBuilder.typeRef(WorkerThreadRunnable))) |
| type.members += field |
| field = group.toField("executorService", _typeReferenceBuilder.typeRef(ExecutorService)) |
| field.static = true |
| type.members += field |
| field = group.toField("dslMetadataService", _typeReferenceBuilder.typeRef(IDSLMetadataService)) [annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = group.toField("dataInterchange", _typeReferenceBuilder.typeRef(IDataInterchange)) [annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = group.toField("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))[annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = group.toField("blobService", _typeReferenceBuilder.typeRef(IBlobService))[annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = group.toField("user", _typeReferenceBuilder.typeRef(IUser))[annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = group.toField("logo", _typeReferenceBuilder.typeRef(Label)) |
| type.members += field |
| field = group.toField("buttons", |
| _typeReferenceBuilder.typeRef(HashMap, _typeReferenceBuilder.typeRef(Button), _typeReferenceBuilder.typeRef(ArrayList, _typeReferenceBuilder.typeRef(String)))) |
| type.members += field |
| field = group.toField("panels", |
| _typeReferenceBuilder.typeRef(HashMap, _typeReferenceBuilder.typeRef(Panel), _typeReferenceBuilder.typeRef(ArrayList, _typeReferenceBuilder.typeRef(String)))) |
| type.members += field |
| } |
| |
| /** |
| * <p>build the constructors to be used by an e4 application.</p> |
| * |
| */ |
| def void toConstructor(JvmDeclaredType type, DataInterchangeGroup group) { |
| type.members += group.toConstructor([ |
| annotations += _annotationTypesBuilder.annotationRef(Inject) |
| parameters += group.toParameter("parent", _typeReferenceBuilder.typeRef(VerticalLayout)) |
| parameters += group.toParameter("context", _typeReferenceBuilder.typeRef(IEclipseContext)) |
| parameters += group.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, DataInterchangeGroup group) { |
| // create view |
| type.members += group.toMethod("createView", _typeReferenceBuilder.typeRef(Void::TYPE), [ |
| parameters += group.toParameter("parent", _typeReferenceBuilder.typeRef(VerticalLayout)) |
| body = [ append('''«group.createView»''')] |
| ]) |
| // create components |
| type.members += group.toMethod("createComponents", _typeReferenceBuilder.typeRef(Void::TYPE), [ |
| body = [ append('''''')] |
| ]) |
| // is duplicate |
| type.members += group.toMethod("isDuplicate", _typeReferenceBuilder.typeRef(boolean), [ |
| parameters += group.toParameter("name", _typeReferenceBuilder.typeRef(String)) |
| body = [ append('''«isDuplicate»''')] |
| ]) |
| // find layout |
| type.members += group.toMethod("findButtonLayout", _typeReferenceBuilder.typeRef(VerticalLayout), [ |
| parameters += group.toParameter("button", _typeReferenceBuilder.typeRef(Button)) |
| body = [ append('''«findButtonLayout»''')] |
| ]) |
| // remove progressbar |
| type.members += group.toMethod("removeProgressBar", _typeReferenceBuilder.typeRef(Void::TYPE), [ |
| parameters += group.toParameter("workerName", _typeReferenceBuilder.typeRef(String)) |
| body = [ append('''«removeProgressBar»''')] |
| ]) |
| // on bundle stopping - shutdown executorService |
| type.members += group.toMethod("bundleChanged", _typeReferenceBuilder.typeRef(Void::TYPE), [ |
| annotations += _annotationTypesBuilder.annotationRef(Override) |
| parameters += group.toParameter("event", _typeReferenceBuilder.typeRef(BundleEvent)) |
| body = [ append('''«bundleChanged»''')] |
| ]) |
| // activate |
| type.members += group.toMethod("activate", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| annotations += _annotationTypesBuilder.annotationRef(PostConstruct) |
| body = [append( |
| ''' |
| user.addUserLocaleListener(this); |
| eventDispatcher.addEventReceiver(this);''')] |
| |
| ]) |
| |
| // deactivate |
| type.members += group.toMethod("deactivate", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| annotations += _annotationTypesBuilder.annotationRef(PreDestroy) |
| body = [append( |
| ''' |
| user.removeUserLocaleListener(this); |
| eventDispatcher.removeEventReceiver(this);''')] |
| ]) |
| // focus |
| type.members += group.toMethod("setFocus", _typeReferenceBuilder.typeRef(Void::TYPE), [ |
| annotations += _annotationTypesBuilder.annotationRef(Focus) |
| body = [append( |
| ''' |
| Component parent = getParent(); |
| while(!(parent instanceof Panel) && parent != null) { |
| parent = parent.getParent(); |
| } |
| if(parent != null) { |
| ((Panel)parent).focus(); |
| }''')] |
| |
| ]) |
| // locale notification |
| type.members += group.toMethod("localeChanged", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| visibility = JvmVisibility.PUBLIC |
| annotations += _annotationTypesBuilder.annotationRef(Override) |
| parameters += group.toParameter("locale", _typeReferenceBuilder.typeRef(Locale)) |
| body = [append('''«group.localeChanged»''')] |
| ]) |
| // event notification |
| type.members += group.toMethod("receiveEvent", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| visibility = JvmVisibility.PUBLIC |
| annotations += _annotationTypesBuilder.annotationRef(Override) |
| parameters += group.toParameter("event", _typeReferenceBuilder.typeRef(EventDispatcherEvent)) |
| body = [append('''«receiveEvent»''')] |
| ]) |
| } |
| |
| /** |
| * let the app wait for finishing the workers before allowing to stop bundle. |
| * |
| * @return code fragment |
| */ |
| def String bundleChanged() { |
| 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. |
| * |
| * @return code fragment |
| */ |
| def String findButtonLayout() { |
| var body = "" |
| body = ''' |
| «body» |
| for (Panel panel : panels.keySet()) { |
| HorizontalLayout buttonCollector = (HorizontalLayout) panel.getContent(); |
| int count = buttonCollector.getComponentCount(); |
| for (int i = 0; i < count; i++) { |
| VerticalLayout buttonLayout = (VerticalLayout) buttonCollector.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. |
| * |
| * @return code fragment |
| */ |
| def String isDuplicate() { |
| var body = "" |
| body = ''' |
| «body» |
| boolean found = false; |
| for(String threadName : progressBars.keySet()) { |
| if (name.equals(threadName)) { |
| found = true; |
| break; |
| } |
| } |
| return found; |
| ''' |
| 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(DataInterchangeGroup group) { |
| var body = ''' |
| getContext().set(IE4Focusable.class, this); |
| buttons = new HashMap<>(); |
| panels = new HashMap<>(); |
| 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(); |
| menuPanel = new Panel(); |
| menuPanel.setSizeFull(); |
| 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 |
| menuPanel.setContent(menu); |
| sidebar.addComponent(menuPanel); |
| sidebar.setExpandRatio(menuPanel, 1.0f); |
| |
| ''' |
| body = ''' |
| «body» |
| // add menu items |
| Button b; |
| VerticalLayout buttonLayout; |
| Panel buttonPanel; |
| HorizontalLayout buttonCollector; |
| ''' |
| for (dataInterchange : group.datInts) { |
| body = ''' |
| «body» |
| buttonPanel = new Panel(); |
| buttonPanel.addStyleName("os-group-panel os-caption-large"); |
| buttonPanel.setCaption("«dataInterchange.name»"); |
| buttonCollector = new HorizontalLayout(); |
| buttonCollector.setMargin(true); |
| buttonPanel.setContent(buttonCollector); |
| panels.put(buttonPanel, new ArrayList<String>(Arrays.asList(new String[] {"«dataInterchange.name»","«dataInterchange.descriptionI18nKey»"}))); |
| 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"); |
| «dataInterchange.getBasicRunConfiguration(false, dataInterchange.getFileURL, WorkerThreadRunnable.Direction.IMPORT.name)» |
| «dataInterchange.defaultVariableName».setName(UUID.randomUUID().toString()); |
| «dataInterchange.defaultVariableName».setEventDispatcher(eventDispatcher); |
| «dataInterchange.defaultVariableName».setUi(UI.getCurrent()); |
| «dataInterchange.defaultVariableName».setDirection(WorkerThreadRunnable.Direction.IMPORT); |
| findButtonLayout(event.getButton()).addComponent(«dataInterchange.defaultVariableName».getProgressBarArea()); |
| progressBars.put(«dataInterchange.defaultVariableName».getName(), «dataInterchange.defaultVariableName»); |
| executorService.execute(«dataInterchange.defaultVariableName»); |
| log.debug("«dataInterchange.name» import added to executor queue"); |
| } |
| }); |
| buttonLayout = new VerticalLayout(); |
| buttonLayout.addComponent(b); |
| buttonCollector.addComponent(buttonLayout); |
| menu.addComponent(buttonPanel); |
| ''' |
| 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"); |
| «dataInterchange.getBasicRunConfiguration(false, dataInterchange.getFileURL, WorkerThreadRunnable.Direction.EXPORT.name)» |
| «dataInterchange.defaultVariableName».setName(UUID.randomUUID().toString()); |
| «dataInterchange.defaultVariableName».setEventDispatcher(eventDispatcher); |
| «dataInterchange.defaultVariableName».setUi(UI.getCurrent()); |
| «dataInterchange.defaultVariableName».setDirection(WorkerThreadRunnable.Direction.EXPORT); |
| findButtonLayout(event.getButton()).addComponent(«dataInterchange.defaultVariableName».getProgressBarArea()); |
| progressBars.put(«dataInterchange.defaultVariableName».getName(), «dataInterchange.defaultVariableName»); |
| executorService.execute(«dataInterchange.defaultVariableName»); |
| log.debug("«dataInterchange.name» export added to executor queue"); |
| } |
| }); |
| buttonLayout = new VerticalLayout(); |
| buttonLayout.addComponent(b); |
| buttonCollector.addComponent(buttonLayout); |
| menu.addComponent(buttonPanel); |
| ''' |
| } |
| body = ''' |
| «body» |
| menu.addStyleName("menu"); |
| menu.setSizeUndefined(); |
| ''' |
| return body |
| } |
| |
| def String getDefaultVariableName(DataInterchange dataInterchange) { |
| return dataInterchange.name.toFirstLower |
| } |
| |
| def String getBasicRunConfiguration(DataInterchange dataInterchange, boolean fqClass, String fileURL, String direction) { |
| var className = "" |
| if (fqClass) { |
| className = DataDSLModelGenerator.pckgName+"."+dataInterchange.name |
| } |
| else { |
| className = dataInterchange.name |
| } |
| return |
| ''' |
| «className» «dataInterchange.getDefaultVariableName» = new «className»(); |
| String url = ProductConfiguration.getDatainterchangeConfiguration(); |
| if(url.isEmpty()) { |
| url = System.getProperty("user.home")+"/.osbee/"+"«(dataInterchange.eContainer as DataInterchangeGroup).name»Config.xml"; |
| } |
| if(!url.endsWith(".xml") ) { |
| if(!(url.endsWith("/") || url.endsWith("\\")) ) { |
| url = url+File.separator; |
| } |
| url = url+"«(dataInterchange.eContainer as DataInterchangeGroup).name»Config.xml"; |
| } |
| File file = new File(url); |
| if(file.exists()) { |
| FileInputStream fileInput; |
| try { |
| fileInput = new FileInputStream(file); |
| Properties properties = new Properties(); |
| properties.loadFromXML(fileInput); |
| fileInput.close(); |
| if(properties.getProperty("«dataInterchange.name»-«direction.toLowerCase()»") == null) { |
| «dataInterchange.getDefaultVariableName».setFileURL("«fileURL»"); |
| } else { |
| «dataInterchange.getDefaultVariableName».setFileURL(properties.getProperty("«dataInterchange.name»-«direction.toLowerCase()»")); |
| } |
| } catch (IOException e) { |
| StringWriter sw = new StringWriter(); |
| e.printStackTrace(new PrintWriter(sw)); |
| log.error("{}", sw.toString()); |
| return; |
| } |
| } else { |
| «dataInterchange.getDefaultVariableName».setFileURL("«fileURL»"); |
| } |
| «dataInterchange.getDefaultVariableName».setPersistenceService(persistenceService); |
| «dataInterchange.getDefaultVariableName».setDataInterchange(dataInterchange); |
| «dataInterchange.getDefaultVariableName».setEventDispatcher(eventDispatcher); |
| «dataInterchange.getDefaultVariableName».setBlobService(blobService); |
| «if(direction.equals(Direction.IMPORT.name)){ |
| '''«dataInterchange.getDefaultVariableName».setDeleteFileAfterImport(«dataInterchange.isDeleteFileAfterImport»);''' |
| }» |
| ''' |
| } |
| |
| 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 "" |
| } |
| |
| /** |
| * <p>build the constructor for each 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("dataInterchange", _typeReferenceBuilder.typeRef(IDataInterchange)) |
| 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("file", _typeReferenceBuilder.typeRef(OutputStream)) |
| type.members += field |
| field = dataInterchange.toField("out", _typeReferenceBuilder.typeRef(OutputStream)) |
| type.members += field |
| field = dataInterchange.toField("exportPath", _typeReferenceBuilder.typeRef(Path)) |
| 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.toGetter("dataInterchange", _typeReferenceBuilder.typeRef(IDataInterchange)) |
| type.members += dataInterchange.toSetter("dataInterchange", _typeReferenceBuilder.typeRef(IDataInterchange)) |
| 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.performInterchange»''')] |
| ]) |
| 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»''')] |
| ]) |
| type.members += dataInterchange.toMethod("getFileURL", _typeReferenceBuilder.typeRef(URL), [ |
| body = [ append('''«dataInterchange.getfileUrl»''')] |
| ]) |
| } |
| |
| /** |
| * Give the fileURL back |
| */ |
| def getfileUrl(DataInterchange interchange){ |
| '''return this.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.isWindowsOS()) { |
| path = filePath.substring("file://".length()); |
| } |
| try { |
| fileURL = new URL(path); |
| } catch (MalformedURLException e1) { |
| if(e1.getMessage().startsWith("unknown protocol") || e1.getMessage().startsWith("no protocol")) { |
| try { |
| fileURL = Paths.get(path).toUri().toURL(); |
| } catch (MalformedURLException e2) { |
| StringWriter sw = new StringWriter(); |
| e2.printStackTrace(new PrintWriter(sw)); |
| log.error("{}", sw.toString()); |
| } |
| } |
| } |
| ''' |
| |
| /** |
| * init 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 = |
| ''' |
| 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 |
| setProgressBarEnabled(true); |
| setProgressIndeterminated(true); |
| if (log.isDebugEnabled()) log.debug("initializing datainterchange factory"); |
| // get entity manager |
| if (log.isDebugEnabled()) log.debug("opening entity manager to persist results"); |
| getPersistenceService().registerPersistenceUnit("«firstEntity.entity.persistenceUnit»", «firstEntity.entity.fullyQualifiedName».class); |
| em = getPersistenceService().getEntityManagerFactory("«firstEntity.entity.persistenceUnit»").createEntityManager(); |
| if(dataInterchange != null) { |
| dataInterchange.open(FrameworkUtil.getBundle(getClass()),"«DSLOutputConfigurationProvider.SMOOKS_OUTPUT_DIRECTORY»/«dataInterchange.name»-"+direction.toString().toLowerCase()+".xml"); |
| dataInterchange.setEventListener(this); |
| dataInterchange.setEntityManager(em); |
| } |
| «IF dataInterchange.createReport» |
| if (log.isDebugEnabled()) log.debug("reporting is on - impacting performance"); |
| if(dataInterchange != null) { |
| String location = FrameworkUtil.getBundle(this.getClass()).getLocation()+"«DSLOutputConfigurationProvider.SMOOKS_OUTPUT_DIRECTORY»/«dataInterchange.name»-"+direction.toString().toLowerCase()+"-report.html"; |
| location = location.replace("reference:file:/", ""); |
| dataInterchange.enableReport(location); |
| } |
| «ENDIF» |
| } catch (TransformerConfigurationException | SAXException | IOException e) { |
| StringWriter sw = new StringWriter(); |
| e.printStackTrace(new PrintWriter(sw)); |
| log.error("{}", sw.toString()); |
| return false; |
| } |
| if(direction == Direction.EXPORT) { |
| int openTry = 0; |
| file = null; |
| URI uri = null; |
| try { |
| uri = fileURL.toURI(); |
| } catch (URISyntaxException e) { |
| StringWriter sw = new StringWriter(); |
| e.printStackTrace(new PrintWriter(sw)); |
| log.error("{}", sw.toString()); |
| return false; |
| } |
| do { |
| exportPath = null; |
| exportPath = Paths.get(uri); |
| try { |
| // find a unique name - similar to given |
| file = Files.newOutputStream(exportPath, 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) { |
| StringWriter sw = new StringWriter(); |
| e.printStackTrace(new PrintWriter(sw)); |
| log.error("{}", sw.toString()); |
| return false; |
| } |
| } catch (IOException e) { |
| StringWriter sw = new StringWriter(); |
| e.printStackTrace(new PrintWriter(sw)); |
| log.error("{}", sw.toString()); |
| return false; |
| } |
| }while(file == null); |
| out = new BufferedOutputStream(file); |
| } |
| return true; |
| ''' |
| return body |
| } |
| |
| /** |
| * use 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 performInterchange(DataInterchange dataInterchange) { |
| var firstEntityBean = (dataInterchange.path.iterator.next as DataInterchangeBean) |
| firstEntityBean.hasBlobMapping = firstEntityBean.mappings.filter(DataInterchangeBlobMapping).size > 0 |
| var body = ''' |
| if(!init(getDirection())) { |
| return; |
| } |
| if(dataInterchange == null) { |
| log.error("dataInterchange is not present - download from www.osbee.org"); |
| return; |
| } |
| try { |
| log.info(getDirection().name()+" - Start of «dataInterchange.name»."); |
| if(getDirection()==WorkerThreadRunnable.Direction.IMPORT) { |
| ''' |
| body = ''' |
| «body» |
| if (importListener != null) { |
| importListener.notifyInitializationStep("datainterchange «dataInterchange.name.toFirstUpper» load.", 0.4, 0.45, 0, 0); |
| } |
| ''' |
| |
| for (path:dataInterchange.path) { |
| for (lookup:path.lookup) { |
| if (lookup.cached) { |
| body = ''' |
| «body» |
| em.setProperty(PersistenceUnitProperties.CACHE_SIZE_+"«lookup.entity.fullyQualifiedName»", "«lookup.cacheSize»"); |
| ''' |
| } |
| } |
| } |
| |
| // import beans as list if no mark latest, other wise as a single bean |
| body = ''' |
| «body» |
| Object result = null; |
| if (log.isDebugEnabled()) log.debug("filtering starts"); |
| setProgressIndeterminated(false); |
| InputStream contents = dataInterchange.openStream(fileURL); |
| setLength(contents.available()); |
| setAvgElementSize(«IF dataInterchange.elementSize==0»10«ELSE»«dataInterchange.elementSize»«ENDIF»); |
| result = dataInterchange.importSource(contents, "«firstEntityBean.entity.name»«IF !firstEntityBean.isMarkLatestImport»List«ENDIF»"«IF dataInterchange.fileEndpoint.encoding !== null», "«dataInterchange.fileEndpoint.encoding»"«ENDIF»); |
| if (log.isDebugEnabled()) log.debug("filtering finished"); |
| em.clear(); // detach eventually attached objects |
| ''' |
| |
| if (!firstEntityBean.isMarkLatestImport) { |
| body = ''' |
| «body» |
| if(result != null) { |
| List<«firstEntityBean.entity.fullyQualifiedName»> «firstEntityBean.entity.name.toFirstLower»List = Arrays.asList((«firstEntityBean.entity.fullyQualifiedName»[]) result); |
| em.getTransaction().begin(); |
| if (log.isDebugEnabled()) log.debug("persisting results"); |
| int total = «firstEntityBean.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(«firstEntityBean.entity.fullyQualifiedName» «firstEntityBean.entity.name.toFirstLower»:«firstEntityBean.entity.name.toFirstLower»List) { |
| ''' |
| if(firstEntityBean.hasBlobMapping && dataInterchange.mode!=EntityManagerMode.REMOVE){ |
| for(mapping:firstEntityBean.mappings){ |
| if(mapping instanceof DataInterchangeBlobMapping){ |
| var m = (mapping as DataInterchangeBlobMapping) |
| var blobFileName = '''«firstEntityBean.entity.name.toFirstLower».get«m.property.name.toFirstUpper»()«IF m.blobFileExtension !== null» + ".«m.blobFileExtension»"«ENDIF»''' |
| body = ''' |
| «body» |
| try (InputStream inputStream = new BufferedInputStream( |
| «IF m.blobPath === null» |
| this.getClass().getClassLoader().getResourceAsStream("/«firstEntityBean.entity.name»/" + «blobFileName») |
| «ELSE» |
| new FileInputStream("«m.blobPath»/" + «blobFileName»)«ENDIF»)) { |
| String «firstEntityBean.entity.name.toFirstLower»_«m.property.name»Id = getBlobService().createBlobMapping( |
| inputStream, |
| «firstEntityBean.entity.name.toFirstLower».get«m.property.name.toFirstUpper»(), |
| "«m.mimeType»" |
| ); |
| «firstEntityBean.entity.name.toFirstLower».set«m.property.name.toFirstUpper»(«firstEntityBean.entity.name.toFirstLower»_«m.property.name»Id); |
| } catch (IOException e) { |
| log.error(e.getLocalizedMessage()); |
| } |
| ''' |
| } |
| } |
| } |
| body = |
| ''' |
| «body» |
| try { |
| «IF dataInterchange.mode==EntityManagerMode.PERSIST»em.persist(«firstEntityBean.entity.name.toFirstLower»); |
| «ELSEIF dataInterchange.mode==EntityManagerMode.MERGE»em.merge(«firstEntityBean.entity.name.toFirstLower»); |
| «ELSEIF dataInterchange.mode==EntityManagerMode.REMOVE»«firstEntityBean.entity.fullyQualifiedName» toBeRemoved = em.merge(«firstEntityBean.entity.name.toFirstLower»); |
| em.remove(toBeRemoved);«ENDIF» |
| } |
| catch (ConstraintViolationException cve) { |
| log.error("«firstEntityBean.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» |
| if(result != null) { |
| «firstEntityBean.entity.fullyQualifiedName» «firstEntityBean.entity.name.toFirstLower» = («firstEntityBean.entity.fullyQualifiedName») result; |
| «firstEntityBean.entity.name.toFirstLower».set«firstEntityBean.latestProperty.name.toFirstUpper»(true); |
| ''' |
| if(firstEntityBean.hasBlobMapping && dataInterchange.mode!=EntityManagerMode.REMOVE){ |
| for(mapping:firstEntityBean.mappings){ |
| if(mapping instanceof DataInterchangeBlobMapping){ |
| var m = (mapping as DataInterchangeBlobMapping) |
| var blobFileName = '''«firstEntityBean.entity.name.toFirstLower».get«m.property.name.toFirstUpper»()«IF m.blobFileExtension !== null» + "." + "«m.blobFileExtension»"«ENDIF»''' |
| body = ''' |
| «body» |
| try (InputStream inputStream = new BufferedInputStream( |
| «IF m.blobPath === null» |
| this.getClass().getClassLoader().getResourceAsStream("/«firstEntityBean.entity.name»/" + «blobFileName») |
| «ELSE» |
| new FileInputStream("«m.blobPath»/" + «blobFileName»)«ENDIF»)) { |
| String «m.property.name.toFirstLower»Id = blobUpload.createBlobMapping( |
| inputStream, |
| «firstEntityBean.entity.name.toFirstLower».get«m.property.name.toFirstUpper»(), |
| "«m.mimeType»", |
| blobAPI |
| ); |
| «firstEntityBean.entity.name.toFirstLower».set«m.property.name.toFirstUpper»(«m.property.name.toFirstLower»Id); |
| } catch (IOException e) { |
| log.error(e.getLocalizedMessage()); |
| } |
| ''' |
| } |
| } |
| } |
| body = ''' |
| «body» |
| em.getTransaction().begin(); |
| if (log.isDebugEnabled()) log.debug("storing results"); |
| «IF dataInterchange.mode==EntityManagerMode.PERSIST»em.persist(«firstEntityBean.entity.name.toFirstLower»); |
| «ELSEIF dataInterchange.mode==EntityManagerMode.MERGE»em.merge(«firstEntityBean.entity.name.toFirstLower»); |
| «ELSEIF dataInterchange.mode==EntityManagerMode.REMOVE»«firstEntityBean.entity.fullyQualifiedName» toBeRemoved = em.merge(«firstEntityBean.entity.name.toFirstLower»); |
| em.remove(toBeRemoved);«ENDIF» |
| if (log.isDebugEnabled()) log.debug("committing results"); |
| em.getTransaction().commit(); |
| ''' |
| } |
| if (firstEntityBean.isMarkLatestImport) { |
| 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 «firstEntityBean.entity.name» set «firstEntityBean.latestProperty.name» = 0").executeUpdate(); |
| em.createQuery("update «firstEntityBean.entity.name» set «firstEntityBean.latestProperty.name» = 1 where id= :id").setParameter("id", «firstEntityBean.entity.name.toFirstLower».getId()).executeUpdate(); |
| if (log.isDebugEnabled()) log.debug("committing mark"); |
| em.getTransaction().commit(); |
| ''' |
| } |
| body = ''' |
| «body» |
| if (log.isDebugEnabled()) log.debug("results persisted"); |
| } else { |
| if (log.isDebugEnabled()) log.debug("no results found"); |
| } |
| if(isDeleteFileAfterImport()){ |
| deleteFile(Paths.get(getFileURL().getPath().substring(1))); // interchange file |
| } |
| ''' |
| |
| var root = dataInterchange.path.findFirst[!it.isMarkLatestImport] |
| if(root !== null) { |
| body = ''' |
| «body» |
| } else { |
| if (log.isDebugEnabled()) log.debug("prepare export"); |
| CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); |
| CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class); |
| Root<«root.entity.fullyQualifiedName»> fr = countQuery.from(«root.entity.fullyQualifiedName».class); |
| countQuery«IF root.exportFilter !== null»«root.exportFilter.buildExportFilterWhereClause("fr")»«ENDIF».select(criteriaBuilder.count(fr)); |
| Long count = em.createQuery(countQuery).getSingleResult(); |
| CriteriaQuery<«root.entity.fullyQualifiedName»> criteriaQuery = criteriaBuilder.createQuery(«root.entity.fullyQualifiedName».class); |
| Root<«root.entity.fullyQualifiedName»> from = criteriaQuery.from(«root.entity.fullyQualifiedName».class); |
| «dataInterchange.buildJoins» |
| CriteriaQuery<«root.entity.fullyQualifiedName»> select = criteriaQuery.multiselect(from); |
| «IF root.exportFilter !== null» |
| select«root.exportFilter.buildExportFilterWhereClause("from")»; |
| «ENDIF» |
| TypedQuery<«root.entity.fullyQualifiedName»> typedQuery = em.createQuery(select); |
| setProgressIndeterminated(false); |
| List<«root.entity.fullyQualifiedName»> allResults = typedQuery.getResultList(); |
| if (log.isDebugEnabled()) log.debug("evaluate root entity count"); |
| setLength(count*«IF dataInterchange.elementSize==0»10«ELSE»«dataInterchange.elementSize»«ENDIF»); |
| setAvgElementSize(1); |
| if (log.isDebugEnabled()) log.debug("root entity count is "+count.toString()); |
| StringWriter writer = new StringWriter(); |
| if(dataInterchange != null) { |
| dataInterchange.exportSource(allResults, writer); |
| } |
| if(count > 0){ out.write(writer.toString().getBytes(«IF dataInterchange.fileEndpoint.encoding !== null»"«dataInterchange.fileEndpoint.encoding»"«ENDIF»));} |
| else{deleteFile(exportPath);} |
| «IF firstEntityBean.markLatestExport» |
| if(allResults != null && !allResults.isEmpty()){ |
| CriteriaQuery cq = criteriaBuilder.createQuery(); |
| Root<«root.entity.fullyQualifiedName»> fr1 = cq.from(«root.entity.fullyQualifiedName».class); |
| List<String> ids = em.createQuery(cq.select(fr1.get("«root.entity.idAttributeName»"))«IF root.exportFilter !== null»«root.exportFilter.buildExportFilterWhereClause("fr1")»«ENDIF»).getResultList(); |
| if (log.isDebugEnabled()) log.debug("mark results as latest export"); |
| em.setProperty(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.Lock); |
| em.getTransaction().begin(); |
| em.createQuery("update «firstEntityBean.entity.name» set «firstEntityBean.latestExpProperty.name» = 1 where «root.entity.idAttributeName» in :ids").setParameter("ids", ids).executeUpdate(); |
| if (log.isDebugEnabled()) log.debug("committing mark export"); |
| em.getTransaction().commit(); |
| } |
| «ENDIF» |
| if (log.isDebugEnabled()) log.debug("export finished"); |
| } |
| log.info(getDirection().name()+" of «dataInterchange.name» successfully ended!"); |
| ''' |
| } else { |
| body = ''' |
| «body» |
| }''' |
| } |
| for (path:dataInterchange.path) { |
| var entity = path.entity |
| body = ''' |
| «body» |
| if(getEventDispatcher() != null) { |
| EventDispatcherEvent «entity.name.toLowerCase»Event = new EventDispatcherEvent(EventDispatcherCommand.REFRESH, "«entity.fullyQualifiedName»", "«dataInterchange.fullyQualifiedName»"); |
| getEventDispatcher().sendEvent(«entity.name.toLowerCase»Event); |
| } |
| ''' |
| } |
| body = ''' |
| «body» |
| } catch (DataInterchangeException | IllegalArgumentException | IOException e) { |
| StringWriter sw = new StringWriter(); |
| e.printStackTrace(new PrintWriter(sw)); |
| log.error(getDirection().name()+" Execution of «dataInterchange.name»: failed due to: {}", sw.toString()); |
| setExecutionFailed(true); |
| } finally { |
| if(file != null) { |
| try { |
| out.close(); |
| file.close(); |
| } catch (IOException e) { |
| StringWriter sw = new StringWriter(); |
| e.printStackTrace(new PrintWriter(sw)); |
| log.error("«dataInterchange.name»:{}", sw.toString()); |
| } |
| } |
| if(dataInterchange != null) { |
| dataInterchange.close(); |
| } |
| if (em != null) { |
| em.close(); |
| } |
| // remove progress bar |
| if(getEventDispatcher() != null) { |
| EventDispatcherEvent evnt = new EventDispatcherEvent(EventDispatcherCommand.FINISHED, getName(), "DataInterchangeWorkerThread"); |
| getEventDispatcher().sendEvent(evnt); |
| } |
| if (log.isDebugEnabled()) log.debug("datainterchange finished"); |
| } |
| ''' |
| return body |
| } |
| |
| /** |
| * handle the worker progress bar. provide the appropriate code. |
| * |
| * @return code fragment |
| */ |
| def String removeProgressBar() { |
| var body = "" |
| body = ''' |
| «body» |
| // a worker notified this view that it is finished |
| if (progressBars.containsKey(workerName)) { |
| final WorkerThreadRunnable worker = progressBars.get(workerName); |
| ((VerticalLayout)worker.getProgressBarArea().getParent()).removeComponent(worker.getProgressBarArea()); |
| progressBars.remove(workerName); |
| } |
| ''' |
| return body |
| } |
| |
| def localeChanged(DataInterchangeGroup group) |
| ''' |
| if(logo != null) { |
| logo.setValue(dslMetadataService.translate(locale.toLanguageTag(), "«group.name»")); |
| } |
| if(buttons != null) { |
| for(Button button: buttons.keySet()) { |
| ArrayList i18nKeys = buttons.get(button); |
| button.setDescription(dslMetadataService.translate(locale.toLanguageTag(),(String)i18nKeys.get(0))+" "+dslMetadataService.translate(locale.toLanguageTag(),(String)i18nKeys.get(2))); |
| } |
| for(Panel panel:panels.keySet()){ |
| ArrayList i18nKeys = panels.get(panel); |
| panel.setCaption(dslMetadataService.translate(locale.toLanguageTag(),(String)i18nKeys.get(1))); |
| } |
| }''' |
| |
| def String receiveEvent() { |
| var body = "" |
| body = ''' |
| «body» |
| switch(event.getCommand()) { |
| case FINISHED: |
| removeProgressBar(event.getTopic()); |
| break; |
| } |
| ''' |
| return body |
| } |
| |
| |
| def String buildExportFilterWhereClause(DataInterchangeExportFilter excludes, String rootname){ |
| var body = "" |
| if(excludes!==null){ |
| var where = excludes.getCondition.buildSubCondition(rootname) |
| if(where !== null && !where.empty){ |
| body = '''.where(«where»)''' |
| } |
| } |
| return body |
| } |
| |
| def String buildSubCondition(DataInterchangeFilterCondition condition, String rootname){ |
| var part1 = "" |
| |
| if(condition !== null && condition.getOperator !== null){ |
| switch(condition.getOperator){ |
| case ISNOTNULL: |
| part1 = '''«rootname».get("«condition.getRefProperty.name»").isNotNull()''' |
| case ISNULL: |
| part1 = '''«rootname».get("«condition.getRefProperty.name»").isNull()''' |
| case EQUALS: |
| if(condition.getValue !== null && !condition.getValue.empty){ |
| part1 = '''criteriaBuilder.equal(«rootname».get("«condition.getRefProperty.name»"), "«condition.getValue»")''' |
| } |
| else{ part1 = null} |
| case NOTEQUALS: |
| if(condition.getValue !== null && !condition.getValue.empty){ |
| part1 = '''criteriaBuilder.notEqual(«rootname».get("«condition.getRefProperty.name»"), "«condition.getValue»")''' |
| } |
| else{ part1 = null} |
| case GREATERTHEN: |
| if(condition.getValue !== null && !condition.getValue.empty){ |
| part1 = '''criteriaBuilder.greaterThan(«rootname».get("«condition.getRefProperty.name»"), "«condition.getValue»")''' |
| } |
| else{ part1 = null} |
| case GREATERTHENOREQUALTO: |
| if(condition.getValue !== null && !condition.getValue.empty){ |
| part1 = '''criteriaBuilder.greaterThanOrEqualTo(«rootname».get("«condition.getRefProperty.name»"), "«condition.getValue»")''' |
| } |
| else{ part1 = null} |
| case LESSTHEN: |
| if(condition.getValue !== null && !condition.getValue.empty){ |
| part1 = '''criteriaBuilder.lessThan(«rootname».get("«condition.getRefProperty.name»"), "«condition.getValue»")''' |
| } |
| else{ part1 = null} |
| case LESSTHENOREQUALTO: |
| if(condition.getValue !== null && !condition.getValue.empty){ |
| part1 = '''criteriaBuilder.lessThanOrEqualTo(«rootname».get("«condition.getRefProperty.name»"), "«condition.getValue»")''' |
| } |
| else{ part1 = null} |
| default: { part1 = null } |
| } |
| |
| if(part1 !== null && condition.getOperator2 !== null && condition.getSubcondition !== null ){ |
| switch(condition.getOperator2){ |
| case AND: return '''criteriaBuilder.and(«part1» , «condition.getSubcondition.buildSubCondition(rootname)» )''' |
| case OR : return '''criteriaBuilder.or(«condition.getSubcondition.buildSubCondition(rootname)» , «part1»)''' |
| default: {return part1 } |
| } |
| } |
| } |
| return part1 |
| |
| } |
| |
| /** |
| * build a graph for all entities in path |
| */ |
| def buildJoins(DataInterchange interchange) { |
| val joinGraph = new JoinGraph<LEntity> |
| // add all entities as nodes that are not indicators for last imported |
| interchange.path.filter[!it.isMarkLatestImport].forEach[joinGraph.addNode(it.entity)] |
| // add all possible oneToMany relations between the given entities |
| interchange.path.filter[!it.isMarkLatestImport].forEach[ |
| val source = it.entity |
| // do not test relations with itself |
| interchange.path.filter[!it.entity.equals(source)].forEach[ |
| val dest = it.entity |
| // get only references of type oneToMany where source and destination match |
| source.features.filter[ |
| ref|ref instanceof LReference && ref.toMany && ref.type instanceof LEntity && ref.type.toName.equals(dest.toName) |
| ].forEach[ref| |
| // add the join with name that was found |
| joinGraph.addJoin(source, dest, ref.name) |
| ] |
| ] |
| ] |
| // calculate all possible paths of the given path |
| var joinManager = new ManageJoins<LEntity>(joinGraph); |
| var joins = joinManager.getAllJoins(interchange.path.findFirst[!it.isMarkLatestImport].entity) |
| // create join commands for criterabuilder if path not empty |
| val output = new StringBuilder |
| joins.filter[!it.empty].forEach[path| |
| output.append("from") |
| path.forEach[join| |
| output.append('''.fetch("«join»", JoinType.LEFT)''') |
| ] |
| output.append(";\n") |
| ] |
| return output.toString |
| } |
| } |