blob: 45dea5b534283853f17f08a5d2f6f520e017072d [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*
*
* This copyright notice shows up in the generated Java code
*
*/
package org.eclipse.osbp.xtext.datainterchange.jvmmodel
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.Component
import com.vaadin.ui.HorizontalLayout
import com.vaadin.ui.Label
import com.vaadin.ui.NativeButton
import com.vaadin.ui.Panel
import com.vaadin.ui.ProgressBar
import com.vaadin.ui.UI
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.PrintWriter
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.Date
import java.util.HashMap
import java.util.List
import java.util.Map
import java.util.MissingResourceException
import java.util.Properties
import java.util.UUID
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.Join
import javax.persistence.criteria.JoinType
import javax.persistence.criteria.ListJoin
import javax.persistence.criteria.Root
import javax.persistence.metamodel.EntityType
import javax.persistence.metamodel.Metamodel
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.TransformerConfigurationException
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.apache.log4j.lf5.util.StreamUtils
import org.eclipse.core.resources.ResourcesPlugin
import org.eclipse.core.runtime.IPath
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.blob.service.BlobService
import org.eclipse.osbp.blob.service.BlobTypingAPI
import org.eclipse.osbp.datainterchange.api.IDataInterchange
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.LAnnotationTarget
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.LFeature
import org.eclipse.osbp.dsl.semantic.common.types.LReference
import org.eclipse.osbp.dsl.semantic.entity.LBean
import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute
import org.eclipse.osbp.dsl.semantic.entity.LEntity
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference
import org.eclipse.osbp.eventbroker.EventBrokerMsg
import org.eclipse.osbp.preferences.ProductConfiguration
import org.eclipse.osbp.runtime.common.annotations.CreateAt
import org.eclipse.osbp.runtime.common.annotations.CreateBy
import org.eclipse.osbp.runtime.common.annotations.Dirty
import org.eclipse.osbp.runtime.common.annotations.UpdateAt
import org.eclipse.osbp.runtime.common.annotations.UpdateBy
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherCommand
import org.eclipse.osbp.ui.api.datamart.IDataMart.EType
import org.eclipse.osbp.utils.entityhelper.DataType
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.DataInterchangeBlobMapping
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeEntityExpression
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeExportHide
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.DataInterchangeFileFixed
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFileXML
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFixedColumnMapping
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFormat
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookup
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookupFilterCondition
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookupFilterOperandProperty
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookupFilterOperandString
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookupMapping
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeMapping
import org.eclipse.osbp.xtext.datainterchange.DataInterchangePackage
import org.eclipse.osbp.xtext.datainterchange.DataInterchangePredefinedExpression
import org.eclipse.osbp.xtext.datainterchange.DataInterchangePropertyMapping
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeSkipMapping
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeValueMapping
import org.eclipse.osbp.xtext.datainterchange.EntityManagerMode
import org.eclipse.osbp.xtext.datainterchange.common.WorkerThreadRunnable
import org.eclipse.osbp.xtext.entitymock.common.IEntityImportInitializationListener
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.EcoreUtil2
import org.eclipse.xtext.generator.IFileSystemAccess
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.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
import org.xml.sax.SAXException
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 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 pkg, IJvmDeclaredTypeAcceptor acceptor) {
pckgName = pkg.name
}
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")
EcoreUtil.getAllContents(EObjectHelper.getSemanticElement(input), false).filter(typeof(DataInterchangePackage)).forEach[
fsa.generatePathConfig(it)
]
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 generatePathConfig(IFileSystemAccess fsa, DataInterchangePackage dataInterchangePkg) {
var dir = new File('''«System.getProperty("user.home")»/.osbee''')
if(!dir.exists) {
dir.mkdir
}
dataInterchangePkg.groups.forEach[
var file = new File('''«System.getProperty("user.home")»/.osbee/«it.name»Config.xml''');
file.setWritable(true, false);
if(!file.exists) {
file.createNewFile
val properties = new Properties();
it.datInts.forEach[
properties.put('''«it.name»-«WorkerThreadRunnable.Direction.EXPORT.toString().toLowerCase()»'''.toString, it.produceAppropiateInterchangeURL(null))
properties.put('''«it.name»-«WorkerThreadRunnable.Direction.IMPORT.toString().toLowerCase()»'''.toString, it.produceAppropiateInterchangeURL(null))
if(it.fileEndpoint instanceof DataInterchangeFileCSV && it.path !== null && it.path.size > 1){
var firstBean = it.path.get(0)
for(bean : it.path){
if(bean !== firstBean){
var dataInterChangeFileName = if(bean.fileName !== null && !bean.fileName.empty) bean.fileName else it.getDataInterchangeFileName.replace(".csv", "_"+firstBean.entity.name+"_"+bean.entity.name+".csv")
properties.put('''«it.name»_«bean.entity.name»-«WorkerThreadRunnable.Direction.EXPORT.toString().toLowerCase()»'''.toString, it.produceAppropiateInterchangeURL(dataInterChangeFileName))
properties.put('''«it.name»_«bean.entity.name»-«WorkerThreadRunnable.Direction.IMPORT.toString().toLowerCase()»'''.toString, it.produceAppropiateInterchangeURL(dataInterChangeFileName))
}
}
}
]
var fileOutput = new FileOutputStream(file);
properties.storeToXML(fileOutput, "dataInterchange file URLs");
fileOutput.close
}
else {
var fileInput = new FileInputStream(file);
val properties = new Properties();
properties.loadFromXML(fileInput)
fileInput.close
it.datInts.forEach[
properties.put('''«it.name»-«WorkerThreadRunnable.Direction.EXPORT.toString().toLowerCase()»'''.toString, it.produceAppropiateInterchangeURL(null))
properties.put('''«it.name»-«WorkerThreadRunnable.Direction.IMPORT.toString().toLowerCase()»'''.toString, it.produceAppropiateInterchangeURL(null))
if(it.fileEndpoint instanceof DataInterchangeFileCSV && it.path !== null && it.path.size > 1){
var firstBean = it.path.get(0)
for(bean : it.path){
var dataInterChangeFileName = if(bean.fileName !== null && !bean.fileName.empty) bean.fileName else it.getDataInterchangeFileName.replace(".csv", "_"+firstBean.entity.name+"_"+bean.entity.name+".csv")
if(bean !== firstBean){
properties.put('''«it.name»_«bean.entity.name»-«WorkerThreadRunnable.Direction.EXPORT.toString().toLowerCase()»'''.toString, it.produceAppropiateInterchangeURL(dataInterChangeFileName))
properties.put('''«it.name»_«bean.entity.name»-«WorkerThreadRunnable.Direction.IMPORT.toString().toLowerCase()»'''.toString, it.produceAppropiateInterchangeURL(dataInterChangeFileName))
}
}
}
]
var fileOutput = new FileOutputStream(file);
properties.storeToXML(fileOutput, "dataInterchange file URLs");
fileOutput.close
}
]
}
/**
* Generates the right file url for both absolute and relative paths.
*/
def String produceAppropiateInterchangeURL(DataInterchange interchange, String subfilename) {
var givenurl = interchange.fileURL
var filename = if(subfilename !== null && !subfilename.empty) subfilename else interchange.dataInterchangeFileName
var directory = interchange.getDataInterchangeDirectoryUrlPath
try {
var url = new URL(givenurl)
if(url.protocol.equals("file")){
// for relative path
if(!Paths.get(directory).absolute){
var projectname = interchange.eResource.URI.segment(1)
var location = findProjectFileOrFolderLocation(projectname, directory, false)
givenurl = location.append(filename).toString
}
}
}
catch (Exception e1) {
if(e1.getMessage().startsWith("unknown protocol") || e1.getMessage().startsWith("no protocol")) {
try{
// check for relative path
if(!Paths.get(directory).absolute){
var projectname = interchange.eResource.URI.segment(1)
var location = findProjectFileOrFolderLocation(projectname, directory, false)
givenurl = location.append(filename).toString
}
}
catch (Exception e2) {}
}
}
// if the path is absolute or from another protocol like http, ftp ...
return givenurl
}
/**
* Returns the path of the given file name or directory name.
*/
def IPath findProjectFileOrFolderLocation(String projectname, String fname, boolean isFile) {
if(projectname !== null && !projectname.empty && fname !== null && !fname.empty){
var project = ResourcesPlugin.workspace.root.getProject(projectname);
if(isFile){
return project.getFile(fname).location
}
return project.getFolder(fname).location
}
return null
}
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
DataInterchangeFileFixed: return (dataInterchange.fileEndpoint as DataInterchangeFileFixed).fileURL
}
return ""
}
/**
* Gives the file path of a data interchange unit without its file name.
*/
def String getDataInterchangeDirectoryUrlPath(DataInterchange interchange){
var modelurl = ""
if(interchange !== null){
var index = interchange.fileURL.lastIndexOf("/")
if( index !== -1) {
modelurl = interchange.fileURL.substring(0, index + 1)
}else{
index = interchange.fileURL.lastIndexOf("\\")
if(index !== -1){
modelurl = interchange.fileURL.substring(0, index + 1)
}
}
}
return modelurl
}
/**
* Gives the file name of a data interchange unit.
*/
def String getDataInterchangeFileName(DataInterchange interchange){
var filename = ""
if(interchange !== null){
var index = interchange.fileURL.lastIndexOf("/")
if( index !== -1) {
filename = interchange.fileURL.substring(index + 1, interchange.fileURL.length)
}else{
index = interchange.fileURL.lastIndexOf("\\")
if(index !== -1){
filename = interchange.fileURL.substring(index + 1, interchange.fileURL.length)
}
}
}
return filename
}
def getUrl(DataInterchange di) {
switch(di.fileEndpoint) {
DataInterchangeFileXML:
return (di.fileEndpoint as DataInterchangeFileXML).fileURL
DataInterchangeFileCSV:
return (di.fileEndpoint as DataInterchangeFileCSV).fileURL
DataInterchangeFileEDI:
return (di.fileEndpoint as DataInterchangeFileEDI).fileURL
DataInterchangeFileFixed:
return (di.fileEndpoint as DataInterchangeFileFixed).fileURL
}
}
def Document createEmptyDocumentForExport(){
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)
return document
}
def void generateExportConfigStub(IFileSystemAccess fsa, DataInterchange dataInterchange) {
dbf.namespaceAware = true
var Document document = null
var csvDocs = <String,Document>newHashMap()
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)
}
if(dataInterchange.path !== null && dataInterchange.path.size >= 1){
dataInterchange.generateCSVExportConfig(csvDocs, dataInterchange.fileEndpoint, delimiter, quote)
}
}
DataInterchangeFileXML: {
if(document === null){document = createEmptyDocumentForExport}
cartridges.put("xmlns:ftl", "http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd")
dataInterchange.generateExportConfig(document, dataInterchange.fileEndpoint, null, null)
}
DataInterchangeFileEDI: {
if(document === null){document = createEmptyDocumentForExport}
}
DataInterchangeFileFixed: {
if(document === null){document = createEmptyDocumentForExport}
cartridges.put("xmlns:ftl", "http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd")
dataInterchange.generateExportConfig(document, dataInterchange.fileEndpoint, null, null)
}
}
if(dataInterchange.fileEndpoint instanceof DataInterchangeFileCSV){
var firstEntityName = dataInterchange.path.get(0).entity.name
for(entityName : csvDocs.keySet){
var doc = csvDocs.get(entityName)
for(cdg:cartridges.keySet) {
doc.documentElement.setAttributeNS("http://www.w3.org/2000/xmlns/", cdg, cartridges.get(cdg))
}
var source = new DOMSource(doc)
var res = new DataResult()
transformer.transform(source, res)
var newBody = res.result
if(entityName === firstEntityName){
fsa.generateFile('''«dataInterchange.name»-«WorkerThreadRunnable.Direction.EXPORT.toString().toLowerCase()».xml''', DSLOutputConfigurationProvider.SMOOKS_OUTPUT_ONCE, newBody)
}
else{
fsa.generateFile('''«dataInterchange.name»_«entityName»-«WorkerThreadRunnable.Direction.EXPORT.toString().toLowerCase()».xml''', DSLOutputConfigurationProvider.SMOOKS_OUTPUT_ONCE, newBody)
}
}
}else{
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 DataResult()
transformer.transform(source, res)
var body = res.result
fsa.generateFile('''«dataInterchange.name»-«WorkerThreadRunnable.Direction.EXPORT.toString().toLowerCase()».xml''', DSLOutputConfigurationProvider.SMOOKS_OUTPUT_ONCE, body)
}
}
def generateCSVExportConfig(DataInterchange dataInterchange, HashMap<String, Document> csvDocs, DataInterchangeFile endPoint, String delimiter, String quote) {
for(bean : dataInterchange.path) {
var vectorMap = <String,String>newHashMap
var fieldList = <LFeature>newArrayList
var String rootEntityName = null
var entityName = (bean.entity as LAnnotationTarget).toName.toString
if (rootEntityName === null && !bean.isMarkLatestImport) {
rootEntityName = (bean.entity as LAnnotationTarget).toName.toString
}
var doc = createEmptyDocumentForExport
var LAttribute prevAttr = null
// create bean attributes if and only if mappings are defined
if(hasAttributeMapping(bean)){
for (f : bean.entity.allFeatures) {
if(useFeature(f, bean, dataInterchange)) {
if(f instanceof LAttribute && f.type instanceof LBean) {
prevAttr = f as LAttribute
} else {
var format = null as DataInterchangeFormat
for (step : bean.format) {
// is there a format modeled for this attribute ?
if ((f as LFeature).toName.equals(step.targetProperty.toName)) {
if (step.format !== null) {
format = step
}
}
}
createExportAttribute(dataInterchange, bean, f, fieldList, vectorMap)
// property.textContent = encodeFreemarker(bean.entity.toName, f, format, "", true, -1, prevAttr?.toName, null)
}
}
// if(f instanceof LEntityAttribute && f.type instanceof LBean) {
// var beanAttr = (f as LEntityAttribute).type as LBean
// for(ba : beanAttr.allFeatures) {
// createExportAttribute(dataInterchange, bean, ba, fieldList, vectorMap)
// }
// }
}
}
createFreemarker(doc, createCsvTemplate(bean, fieldList, delimiter, quote, dataInterchange.path), endPoint)
csvDocs.put(entityName, doc)
}
}
def void generateImportConfigStub(IFileSystemAccess fsa, DataInterchange dataInterchange) {
var location = "Workspace://"+EcoreUtil2.getPlatformResourceOrNormalizedURI(dataInterchange).segmentsList.get(1)+"/"
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 = <LFeature>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.makePath(location)
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.makePath(location)
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.makePath(location)
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)
}
DataInterchangeFileFixed: {
cartridges.put("xmlns:fl", "http://www.milyn.org/xsd/smooks/fixed-length-1.3.xsd")
pval = new ParameterValue
pval.value = "input.txt"
parameters.put("inputType", pval)
pval = new ParameterValue
pval.value = (dataInterchange.fileEndpoint as DataInterchangeFileFixed).fileURL.makePath(location)
pval.modifiers.put("type", "input.type.actived")
parameters.put("input.txt", pval)
dataInterchange.generateImportConfig(fieldList, document, dataInterchange.fileEndpoint)
(dataInterchange.fileEndpoint as DataInterchangeFileFixed).input(dataInterchange, fieldList, 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 DataResult()
transformer.transform(source, res)
body = res.result
fsa.generateFile('''«dataInterchange.name»-«WorkerThreadRunnable.Direction.IMPORT.toString().toLowerCase()».xml''', DSLOutputConfigurationProvider.SMOOKS_OUTPUT_ONCE, body)
}
def String makePath(String fileURL, String location) {
var path = Paths.get(fileURL)
if(path.absolute) {
return fileURL
} else {
return location + fileURL
}
}
def input(DataInterchangeFileXML xml, DataInterchange interchange, Document doc) {
}
def input(DataInterchangeFileCSV csv, DataInterchange interchange, List<LFeature> fieldList, Document doc) {
var reader = doc.createElement("csv:reader")
var fields = doc.createAttribute("fields")
var fldList = <String>newArrayList
var mappingInterchanges = interchange.path.filter[it.hasAttributeMapping]
var lookupInterchanges = interchange.path.filter[it.hasReferenceLookup]
if(mappingInterchanges.empty){
for(f:fieldList) {
if(f instanceof LEntityAttribute || f instanceof LBeanAttribute){
fldList.add(f.toName)
}else if(f instanceof LEntityReference && lookupInterchanges.length > 0){
// add reference only if they are specified by lookup
// as a consequence they are located at the end of the list
for(li:lookupInterchanges){
for(lup:li.lookup){
if(!fldList.contains(lup.dataMap) && f.name.equals(lup.dataMap)){
fldList.add(f.toName)
}
}
}
}
}
} else {
for(mi:mappingInterchanges){
for(mapping:mi.mappings){
if(mapping instanceof DataInterchangePropertyMapping) {
if(!(mapping instanceof DataInterchangeBlobMapping)) {
fldList.add(mapping.data)
}
} else {
if(mapping instanceof DataInterchangeLookupMapping) {
fldList.add(mapping.lookupReference.toName)
}
if(mapping instanceof DataInterchangeSkipMapping) {
fldList.add(mapping.name)
}
}
}
}
}
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 input(DataInterchangeFileFixed fixed, DataInterchange interchange, List<LFeature> fieldList, Document doc) {
var reader = doc.createElement("fl:reader")
var fields = doc.createAttribute("fields")
var fldList = <String>newArrayList
var iter = interchange.path.iterator
if(iter.hasNext) {
var path = iter.next
for(map:path.mappings) {
var column = map as DataInterchangeFixedColumnMapping
fldList.add(column.createFixedLengthField)
}
fields.textContent = fldList.join(",")
reader.attributeNode = fields
}
doc.documentElement.appendChild(reader)
}
def String createFixedLengthField(DataInterchangeFixedColumnMapping f) {
var body = '''«f.property.toName»[«f.length»]'''
var isFirst = true
if(f.trim) {
body = '''«body»«IF isFirst»?«ELSE».«ENDIF»trim'''
isFirst = false
}
if(f.leftTrim) {
body = '''«body»«IF isFirst»?«ELSE».«ENDIF»left_trim'''
isFirst = false
}
if(f.rightTrim) {
body = '''«body»«IF isFirst»?«ELSE».«ENDIF»right_trim'''
isFirst = false
}
if(f.upperCase) {
body = '''«body»«IF isFirst»?«ELSE».«ENDIF»upper_case'''
isFirst = false
}
if(f.lowerCase) {
body = '''«body»«IF isFirst»?«ELSE».«ENDIF»lower_case'''
isFirst = false
}
if(f.capFirst) {
body = '''«body»«IF isFirst»?«ELSE».«ENDIF»cap_first'''
isFirst = false
}
if(f.uncapFirst) {
body = '''«body»«IF isFirst»?«ELSE».«ENDIF»uncap_first'''
isFirst = false
}
if(f.capitalize) {
body = '''«body»«IF isFirst»?«ELSE».«ENDIF»capitalize'''
isFirst = false
}
return body
}
def createFreemarker(Document doc, String templateString, DataInterchangeFile endPoint) {
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('''«IF endPoint.encoding !== null»<#ftl encoding='«endPoint.encoding»'>«ENDIF»«IF endPoint.locale !== null»<#setting locale="«endPoint.locale»">«ENDIF»'''+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
var done = false
while(node !== null && (!node.nodeName.equals("jb:value") || (node.attributes.getNamedItem("property") !== null) && !done)) { /* && !node.attributes.getNamedItem("property").nodeValue.equals(propertyName)))) {*/
var nval = node.attributes.getNamedItem("property")?.nodeValue
if(propertyName.equals(nval)) {
done = true
} else {
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 || type == EType.TIMESTAMP) {
var defaultValue = doc.createAttribute("default")
defaultValue.textContent = "null"
value.attributeNode = defaultValue
}
return value
}
def addMapping(Document doc, Element parent, String propertyName, String dataName, boolean byAttribute) {
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") !== null && !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»/«IF byAttribute»@«ENDIF»«dataName»'''
value.attributeNode = data
}
def Element createDecodeParam(String prefix, Document doc, Element parent, String paramName, String paramValue) {
var param = doc.createElement(prefix+":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) {
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 = "true"
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, boolean byAttribute) {
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")
var paramContent = paramValue
if(paramValue.equalsIgnoreCase("int")){
paramContent = "Integer"
}
decoder.textContent = paramContent
daoValue.attributeNode = decoder
// mapping given?
if(dataMap !== null) {
var data = doc.createAttribute("data")
data.textContent = '''«elementMap»/«IF byAttribute»@«ENDIF»«dataMap»'''
daoValue.attributeNode = data
}
return daoValue
}
def Element createDaoInserter(Document doc, String beanIdName, String elementMap) {
var inserter = doc.createElement("dao:inserter")
doc.documentElement.appendChild(inserter)
var beanId = doc.createAttribute("beanId")
beanId.textContent = beanIdName
inserter.attributeNode = beanId
if(elementMap !== null) {
var create = doc.createAttribute("insertOnElement")
create.textContent = elementMap
inserter.attributeNode = create
}
return inserter
}
def generateExportConfig(DataInterchange dataInterchange, Document doc, DataInterchangeFile endPoint, String delimiter, String quote) {
var substitutionMap = <String,String>newHashMap
var vectorMap = <String,String>newHashMap
var substitutionCount = 0
var fieldList = <LFeature>newArrayList
var String rootEntityName = null
var Document ftlDocument = null
var Element bean = null
var Element oldParent = null
var vector = "vector"
var depth = 0
var LEntity previousEntity = null
// iterate through all path (bean) listed under `path` keyword
for(path : dataInterchange.path) {
if (rootEntityName === null && !path.isMarkLatestImport) {
rootEntityName = (path.entity as LAnnotationTarget).toName.toString
}
if (dataInterchange.fileEndpoint instanceof DataInterchangeFileXML) {
var currentKey = '''list«substitutionCount»'''
if(ftlDocument === null) {
ftlDocument = domImpl.createDocument(null, '''«IF dataInterchange.vectorName !== null»«dataInterchange.vectorName»«ELSE»vector«ENDIF»''', null)
}
vector = vectorMap.get(path.entity.toName) ?: vector
substitutionMap.put(currentKey, '''«vector» as «path.entity.toName»''')
if(previousEntity !== null && !previousEntity.hasRelation(path.entity)){
bean = createXmlBean(ftlDocument, oldParent, path.entity, path.format, currentKey, path, dataInterchange)
}else{
oldParent = bean
bean = createXmlBean(ftlDocument, bean, path.entity, path.format, currentKey, path, dataInterchange)
depth = depth + 1
}
substitutionCount = substitutionCount + 1
previousEntity = path.entity
}
for (f : path.entity.allFeatures) {
createExportAttribute(dataInterchange, path, f, fieldList, vectorMap)
if(f instanceof LEntityAttribute && f.type instanceof LBean) {
var beanAttr = (f as LEntityAttribute).type as LBean
for(ba : beanAttr.allFeatures) {
createExportAttribute(dataInterchange, path, ba, fieldList, vectorMap)
}
}
}
}
// if(endPoint instanceof DataInterchangeFileCSV) {
// createFreemarker(doc, createCsvTemplate(rootEntityName, fieldList, delimiter, quote, dataInterchange.path), endPoint)
// }
if(endPoint instanceof DataInterchangeFileXML) {
createFreemarker(doc, createXmlTemplate(ftlDocument, substitutionMap, dataInterchange.path), endPoint)
}
if(endPoint instanceof DataInterchangeFileFixed) {
createFreemarker(doc, createFixedTemplate(rootEntityName, fieldList, dataInterchange.path), endPoint)
}
}
def createExportAttribute(DataInterchange dataInterchange, DataInterchangeBean path, LFeature f, List<LFeature> fieldList, Map<String, String> vectorMap) {
if(dataInterchange.getExportFilter === null && f instanceof LAttribute && !f.toMany ||
dataInterchange.getExportFilter !== null &&
f instanceof LAttribute && !f.toMany &&
dataInterchange.getExportFilter.hiddenproperties !== null &&
!dataInterchange.getExportFilter.hiddenproperties.empty &&
!dataInterchange.getExportFilter.hiddenproperties.toList.containsFeature(f)) {
if(useFeature(f, path, dataInterchange)) {
fieldList.add(f)
}
}
if(f instanceof LReference && !f.toMany && path.lookupKeys.empty) {
fieldList.add(f)
}
// if a feature is a 1-* reference, find if the referenced entity is also under this path.
if(f instanceof LReference && f.toMany && !path.isMarkLatestImport) {
var iter = dataInterchange.path.iterator
var next = iter.next
// find current entity
while (iter.hasNext && next.entity.toName != path.entity.toName) {
next = iter.next
}
while (iter.hasNext) {
// move to next entity
next = iter.next
if (next !== null && next.entity.toName == (f.type as LEntity).toName) {
if(next.refDataSource !== null){
vectorMap.put(next.entity.toName, '''«path.entity.toName».«next.refDataSource.name»''')
}
else{
vectorMap.put(next.entity.toName, '''«path.entity.toName».«f.name»''')
}
}
}
}
}
def boolean hasRelation(LEntity root, LEntity entity) {
var result = root.features.filter[it instanceof LReference && (it as LReference).type.equals(entity)]
return !result.empty
}
def generateImportConfig(DataInterchange dataInterchange, List<LFeature> fieldList, Document doc, DataInterchangeFile endPoint) {
var isFirst = true
var autoMapping = ""
var byAttribute = false
var isMarked = false
switch(endPoint) {
DataInterchangeFileCSV:
autoMapping = "/csv-set"
DataInterchangeFileXML: {
autoMapping = '''«IF dataInterchange.vectorName !== null»«dataInterchange.vectorName»«ELSE»vector«ENDIF»'''
byAttribute = endPoint.byAttribute
}
DataInterchangeFileEDI: {}
DataInterchangeFileFixed:
autoMapping = "/set"
}
for(path : dataInterchange.path) {
var map = ""
if(path.elementMap === null) {
map = autoMapping
} else {
map = path.elementMap
}
var Element bean = null
if(!path.isMarkLatestImport && isFirst) {
var rootBean = createBean(doc, path.entity.toName+"List", path.entity.fullyQualifiedName.toString, map, true)
createWiring(doc, rootBean, path.entity.toName, null, null)
isFirst = false
} else {
isMarked = true
}
switch(endPoint) {
DataInterchangeFileCSV: {
if(!path.isMarkLatestImport) {
autoMapping = autoMapping + "/csv-record"
}
}
DataInterchangeFileXML: {
autoMapping = '''«autoMapping»/«IF path.nodeName !== null»«path.nodeName»«ELSE»«path.entity.toName»«ENDIF»'''
}
DataInterchangeFileEDI: {}
DataInterchangeFileFixed: {
autoMapping = autoMapping + "/record"
}
}
if(path.elementMap === null) {
map = autoMapping
} else {
map = path.elementMap
}
bean = createBean(doc, path.entity.toName, path.entity.fullyQualifiedName.toString, map, false)
// if merge or remove - create a locator for id and version
if(dataInterchange.mode != EntityManagerMode.PERSIST) {
if(!path.lookupKeys.empty) {
createExpression(doc, bean, path.entity.idAttributeName, "?"+path.entity.toName+"Merger."+path.entity.idAttributeName)
if(path.entity.versionAttribute !== null) {
createExpression(doc, bean, path.entity.versionAttributeName, "?"+path.entity.toName+"Merger."+path.entity.versionAttributeName)
}
var locator = createDaoLocator(doc, null, path.entity.toName+"Merger", map, true)
createDaoQuery(doc, locator, path.queryKeys)
createLookupKeys(path, doc, locator, map, byAttribute, endPoint)
}
else if(path.entity.versionAttribute !== null) {
createExpression(doc, bean, path.entity.versionAttributeName, "?"+path.entity.toName+"Merger."+path.entity.versionAttributeName)
var locator = createDaoLocator(doc, null, path.entity.toName+"Merger", map, true)
createDaoQuery(doc, locator, path.queryVersion)
createDaoParam(doc, locator, '''param''', path.entity.primaryKeyAttribute.decoder, map, path.entity.idAttributeName, byAttribute)
}
} else if(!isMarked && !path.hasBlob) {
createDaoInserter(doc, path.entity.toName, map)
}
// are there any mappings?
var mappingFound = hasAttributeMapping(path)
for (f : path.entity.allFeatures) {
switch f {
LAttribute: {
if (!f.toMany) {
// enable mapping for this field
// if not disposed and not latest marker and not id except no lookup keys given and mode is not persist
if (!isInternal(f) && (!isId(f) || (path.lookupKeys.empty && dataInterchange.mode != EntityManagerMode.PERSIST))
&& (!path.isMarkLatestImport || !path.latestProperty.toName.equals(f.toName))) {
// add to the level's field list
if (!path.isMarkLatestImport) {
if((f as LEntityAttribute).type instanceof LBean) {
var beanAttr = (f as LEntityAttribute).type as LBean
for(ba : beanAttr.allAttributes) {
fieldList.add(ba)
}
} else {
fieldList.add(f)
}
}
if(bean !== null) {
if((f as LEntityAttribute).type instanceof LBean) {
var beanAttr = (f as LEntityAttribute).type as LBean
var subBean = createBean(doc, beanAttr.toName, beanAttr.fullyQualifiedName.toString, map, false)
for(ba : beanAttr.allAttributes) {
createImportAttribute(path, ba, doc, subBean, byAttribute, endPoint, mappingFound)
}
createWiring(doc, bean, beanAttr.toName, null, f.toSetter.simpleName)
} else {
createImportAttribute(path, f, doc, bean, byAttribute, endPoint, mappingFound)
}
}
}
}
}
// 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.toAdder(f.name).simpleName)
}
}
} else {
// many to one
if(path.lookup.isEmpty) {
fieldList.add(f as LEntityReference)
var field = (f as LEntityReference).type.primaryKeyAttribute
var etype = dtType.getBasicType(field)
for(mapping : path.mappings) {
if(mapping instanceof DataInterchangePropertyMapping) {
if(f.name.equals(mapping.property.name)) {
createProperty(doc, bean, f.toName, field.decoder, etype)
addMapping(doc, bean, f.toName, mapping.data, byAttribute)
}
}
}
} else {
// generate possible lookups for this many to one relationship
var paramCnt = 0
for (lookup : path.lookup) {
// entity and property must match
if (lookup.targetProperty.toName.equals((f as LReference).name)) {
if(endPoint instanceof DataInterchangeFileCSV){
// the field will need to be included for header
fieldList.add(f as LEntityReference)
}
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)
createDaoQuery(doc, locator, (f.type as LEntity).query(lookup, paramCnt))
createDaoParam(doc, locator, '''param«paramCnt»''', lookup.queryProperty.type.name.toFirstUpper, lookup.elementMap, lookup.dataMap, byAttribute)
paramCnt ++
if(lookup.condition !== null && lookup.condition.operand instanceof DataInterchangeLookupFilterOperandProperty && !lookup.condition.operator.literal.startsWith("is")) {
var prop = (lookup.condition.operand as DataInterchangeLookupFilterOperandProperty).refProperty
for(mapping:path.mappings) {
if(mapping instanceof DataInterchangePropertyMapping) {
if(mapping.property.equals(prop)) {
if(mapping.data === null) {
createDaoParam(doc, locator, '''param«paramCnt»''', prop.type.name.toFirstUpper, autoMapping, prop.toName, byAttribute)
} else {
createDaoParam(doc, locator, '''param«paramCnt»''', prop.type.name.toFirstUpper, mapping.data, prop.toName, byAttribute)
}
paramCnt ++
}
}
}
}
if(lookup.condition !== null && lookup.condition.subcondition !== null) {
lookup.condition.subcondition.iterateConditionParameter(doc, locator, path.mappings, autoMapping, paramCnt, byAttribute)
}
}
}
}
}
}
}
}
}
}
def createImportAttribute(DataInterchangeBean path, LAttribute f, Document doc, Element parentElement, boolean byAttribute, DataInterchangeFile endPoint, boolean mappingFound) {
// scan expressions for this field
var expressionFound = path.createAttributeExpression(f, doc, parentElement)
// scan formats for this field
var formatFound = path.createAttributeFormat(f, doc, parentElement, endPoint)
// default for mapping purposes
if (!expressionFound && !formatFound) {
// create no property for unmapped marker entities
if (!(endPoint instanceof DataInterchangeFileCSV) || !path.isMarkLatestImport) {
// create no property if mapping is used and this attribute is unmapped
if(!mappingFound || path.mappings.isMapped(f)) {
path.createAttributeMapping(f as LAttribute, doc, parentElement, endPoint)
}
}
}
createAttributeMapping(path, f, doc, parentElement, byAttribute)
// default mapping for xml and csv
if (!mappingFound && !path.isMarkLatestImport && (endPoint instanceof DataInterchangeFileXML||endPoint instanceof DataInterchangeFileCSV)) {
addMapping(doc, parentElement, f.toName, f.toName, byAttribute)
}
}
def boolean isId(LFeature f) {
if(f instanceof LEntityAttribute) {
return (f as LEntityAttribute).id || (f as LEntityAttribute).uuid
}
return false
}
protected def boolean hasBlob(DataInterchangeBean path) {
for(mapping : path.mappings) {
if(mapping instanceof DataInterchangeBlobMapping) {
return true
}
}
}
protected def void createAttributeMapping(DataInterchangeBean path, LAttribute f, Document doc, Element parentElement, boolean byAttribute) {
for(mapping : path.mappings) {
switch(mapping) {
DataInterchangePropertyMapping: {
if(f.name.equals(mapping.property.name)) {
if(mapping.data === null || mapping.data.empty) {
addMapping(doc, parentElement, f.toName, f.toName, byAttribute)
} else {
addMapping(doc, parentElement, f.toName, mapping.data, byAttribute)
}
}
}
DataInterchangeLookupMapping: {}
DataInterchangeSkipMapping: {}
}
}
}
def createAttributeMapping(DataInterchangeBean path, LAttribute f, Document doc, Element parentElement, DataInterchangeFile endPoint) {
var etype = dtType.getBasicType(f)
// add enum decoder
if(etype == EType.LENUM){
var value = createProperty(doc, parentElement, f.toName, "Enum", etype)
createDecodeParam("jb", doc, value, "enumType", f.type.toQualifiedName.toString)
var enumsliterals = f.type.eContents;
for(literal : enumsliterals){
val enumname = literal.fullyQualifiedName.lastSegment
// extra fileds
createDecodeParam("jb", doc, value, enumsliterals.indexOf(literal).toString, enumname)
// mandatory fields
createDecodeParam("jb", doc, value, enumname, enumname)
}
}
else{
// add format decoder
var Element value = null
value = createProperty(doc, parentElement, f.toName, f.decoder, etype)
createDefaultDecoderFormat("jb", doc, value, f, endPoint)
}
}
protected def createDefaultDecoderFormat(String prefix, Document doc, Element parentElement, LAttribute f, DataInterchangeFile endPoint) {
var etype = dtType.getBasicType(f)
if (etype == EType.DATE || etype == EType.TIMESTAMP) {
createDecodeParam(prefix, doc, parentElement, "format", "yyyy-MM-dd'T'HH:mm:ss")
} else if((etype == EType.DOUBLE || etype == EType.FLOAT) && endPoint.locale !== null) {
createDecodeParam(prefix, doc, parentElement, "format", "#.######")
if (endPoint.locale !== null) {
createDecodeParam(prefix, doc, parentElement, "locale-language", endPoint.locale.split("_").get(0))
if(endPoint.locale.split("_").size > 1) {
createDecodeParam(prefix, doc, parentElement, "locale-country", endPoint.locale.split("_").get(1))
}
}
}
}
protected def boolean createAttributeFormat(DataInterchangeBean path, LAttribute f, Document doc, Element parentElement, DataInterchangeFile endPoint) {
var formatFound = false
for (format : path.format) {
// is there a format modeled for this attribute ?
if (f.toName.equals(format.targetProperty.toName)) {
var value = createProperty(doc, parentElement, f.toName, f.decoder, dtType.getBasicType(f))
if(format.format !== null) {
createDecodeParam("jb", doc, value, "format", format.format)
if (endPoint.locale !== null) {
createDecodeParam("jb", doc, value, "locale-language", endPoint.locale.split("_").get(0))
if(endPoint.locale.split("_").size > 1) {
createDecodeParam("jb", doc, value, "locale-country", endPoint.locale.split("_").get(1))
}
}
}
formatFound = true
}
}
return formatFound
}
protected def boolean createAttributeExpression(DataInterchangeBean path, LAttribute f, Document doc, Element parentElement) {
var expressionFound = false
for (expr : path.expression) {
switch(expr) {
DataInterchangeEntityExpression: {
// is there an entity expression for this attribute ?
if (f.toName.equals((expr as DataInterchangeEntityExpression).targetProperty.toName)) {
createExpression(doc, parentElement, f.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.toName.equals((expr as DataInterchangePredefinedExpression).targetProperty.toName)) {
if("UUID".equals((expr as DataInterchangePredefinedExpression).bean.literal)) {
createExpression(doc, parentElement, f.toName, "PUUID."+(expr as DataInterchangePredefinedExpression).beanType.getName)
} else {
createExpression(doc, parentElement, f.toName, "PTIME."+(expr as DataInterchangePredefinedExpression).bean.getName+(expr as DataInterchangePredefinedExpression).beanType.getName)
}
expressionFound = true
}
}
}
}
return expressionFound
}
protected def void createLookupKeys(DataInterchangeBean path, Document doc, Element locator, String map, boolean byAttribute, DataInterchangeFile endPoint) {
var pCnt = 0
for(key:path.lookupKeys) {
if(key.property.eContainer.equals(path.entity)) {
var daoValue = createDaoParam(doc, locator, '''param«pCnt»''', key.property.decoder, map, path.mappings.mapElement(key.property.name), byAttribute)
createDefaultDecoderFormat("dao", doc, daoValue, key.property, endPoint)
} else {
for(lookup:path.lookup) {
if(lookup.queryProperty.equals(key.property)) {
var daoValue = createDaoParam(doc, locator, '''param«pCnt»''', key.property.decoder, map, lookup.elementMap.replace(map, "").replace("//", ""), byAttribute)
createDefaultDecoderFormat("dao", doc, daoValue, key.property, endPoint)
}
}
}
pCnt ++
}
}
def boolean hasAnnotation(LFeature feature, Class<?> annotationType) {
for(anno:(feature).annotationInfo.annotations) {
if (anno.annotation.annotationType.fullyQualifiedName.toString.equals(annotationType.name)) {
return true;
}
}
return false;
}
def boolean isInternal(LFeature f) {
if("disposed".equals(f.toName)) {
return true
}
if(f instanceof LEntityAttribute) {
if((f as LEntityAttribute).version) {
return true
}
if(f.hasAnnotation(Dirty) || f.hasAnnotation(UpdateAt) || f.hasAnnotation(UpdateBy) || f.hasAnnotation(CreateAt) || f.hasAnnotation(CreateBy)) {
return true
}
}
return false
}
protected def boolean hasAttributeMapping(DataInterchangeBean path) {
for(mapping : path.mappings) {
if(mapping instanceof DataInterchangePropertyMapping) {
for (a : path.entity.allAttributes) {
if(a.name.equals(mapping.property.name)) {
return true
}
}
}
}
return false
}
protected def boolean hasReferenceLookup(DataInterchangeBean path){
for(lu : path.lookup) {
for(a : path.entity.getAllReferences) {
if(a.name.equals(lu.dataMap)){
return true
}
}
}
return false
}
protected def boolean hasReferenceExport(DataInterchangeBean path){
for(expose : path.exportExposes) {
for(a : path.entity.getAllReferences) {
if(a.name.equals(expose.refEntity.name)){
return true
}
}
}
return false
}
def boolean isMapped(EList<DataInterchangeMapping> list, LFeature attribute) {
if(attribute instanceof LEntityAttribute) {
return !list.filter[it instanceof DataInterchangePropertyMapping && (it as DataInterchangePropertyMapping).property.name.equals(attribute.name)].empty
}
return false;
}
def String mapElement(EList<DataInterchangeMapping> mappings, String propertyName) {
var element = (mappings.findFirst[it instanceof DataInterchangePropertyMapping && (it as DataInterchangePropertyMapping).property.name.equals(propertyName) && it instanceof DataInterchangeValueMapping] as DataInterchangeValueMapping)?.data
if(element === null) {
element = propertyName
}
return element
}
def Element createXmlBean(Document doc, Element parent, LEntity entity, EList<DataInterchangeFormat> formats, String currentKey, DataInterchangeBean path, DataInterchange dataInterchange) {
var LAttribute prevAttr = null
var bean = doc.createElement('''«IF path.nodeName !== null»«path.nodeName»«ELSE»«entity.toName»«ENDIF»''')
var pi = doc.createProcessingInstruction(currentKey, "")
if(parent === null) {
doc.documentElement.appendChild(pi)
doc.documentElement.appendChild(bean)
} else {
bean = doc.createElement('''«IF path.nodeName !== null»«path.nodeName»«ELSE»«entity.toName»«ENDIF»''')
parent.appendChild(pi)
parent.appendChild(bean)
}
for(p:entity.allAttributes) {
if(useFeature(p, path, dataInterchange)) {
if(p instanceof LAttribute && p.type instanceof LBean) {
prevAttr = p as LAttribute
} else {
var format = null as DataInterchangeFormat
for (step : formats) {
// is there a format modeled for this attribute ?
if ((p as LFeature).toName.equals(step.targetProperty.toName)) {
if (step.format !== null) {
format = step
}
}
}
var property = doc.createElement(p.toName)
property.textContent = encodeFreemarker(entity.toName, p, format, "", true, -1, prevAttr?.toName, null)
bean.appendChild(property)
}
}
}
for(e : path.exportExposes){
var expose = e
var segments = <String>newArrayList()
segments.add(expose.refEntity.name)
while(expose.refProperty === null){
expose = expose.subExpose
segments.add(expose.refEntity.name)
}
var property = doc.createElement(expose.refProperty.toName)
var pathToProperty = segments.join(".")
property.textContent = encodeFreemarker('''«entity.toName».«pathToProperty»''', expose.refProperty, null as DataInterchangeFormat, "", true, -1, "", segments)
bean.appendChild(property)
}
var pa = doc.createProcessingInstruction(currentKey, "")
if(parent === null) {
doc.documentElement.appendChild(pa)
} else {
parent.appendChild(pa)
}
return bean
}
def boolean useFeature(LFeature f, DataInterchangeBean path, DataInterchange dataInterchange) {
var mappingFound = hasAttributeMapping(path)
if (!isInternal(f) && // don't export version etc.
!path.isMarkLatestImport && (!mappingFound || path.mappings.isMapped(f))) {
if(dataInterchange.mode == EntityManagerMode.PERSIST) {
if(isId(f)) {
return false
}
return true
} else {
return true
}
}
return false
}
def String decoder(LFeature f) {
return getPrimitiveDataTypeName(f as LAttribute)
}
def String decoder(LEntityAttribute f) {
return getPrimitiveDataTypeName(f)
}
def String getPrimitiveDataTypeName(LAttribute attribute) {
var eType = dtType.getBasicType(attribute)
var String typeName = null
if (eType == EType.DATE || eType == EType.TIMESTAMP) {
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, EList<DataInterchangeBean> path) {
var source = new DOMSource(doc)
var res = new DataResult()
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(source, res)
var output = res.result
var DataInterchange interchange = null
// processing the template string for filtered information
for(f: path){ // for exclusion
if(f.eContainer instanceof DataInterchange){
interchange = f.eContainer as DataInterchange
}
if(interchange !== null && interchange.getExportFilter !== null && interchange.getExportFilter.hiddenproperties !== null && !interchange.getExportFilter.hiddenproperties.empty){
for(hiddenprop : interchange.getExportFilter.hiddenproperties){
var attrname = hiddenprop.property.name
if(output.contains(attrname)){
var targetstatement = output.substring(output.indexOf("<"+attrname+">${("+f.entity.name),output.indexOf("</"+attrname+">") + ("</"+attrname+">").length)
output = output.replace(targetstatement, "")
}
}
}
}
// cleaning whitespaces
var result = ""
for(f : output.split("\r")){
if(!f.trim.isEmpty){
result = result.concat(f)
}
}
// processing instructions are embedded in question marks - they must be replaced
for(k:substitutionMap.keySet) {
result = result.replaceFirst(k, '''#list «substitutionMap.get(k)»''')
}
for(l:substitutionMap.keySet) {
result = result.replaceFirst(l, '''/#list''')
}
return result.replace("&lt;","<").replace("&gt;",">").replace("<?","<").replace("?>",">")//.replace("</#","\n</#")
}
def String createCsvTemplate(DataInterchangeBean bean, List<LFeature> fieldList, String delimiter, String quote, EList<DataInterchangeBean> paths) {
var rootEntityName = (bean.entity as LAnnotationTarget).toName.toString
var tmpList = <String>newArrayList()
var fldList = <String>newArrayList
var LAttribute prevAttr = null
for(field:fieldList) {
if(field instanceof LAttribute && field.type instanceof LBean) {
prevAttr = field as LAttribute
} else {
tmpList.add(encodeFreemarker(rootEntityName, field, paths, quote, false, -1, prevAttr?.toName))
fldList.add(field.toName)
}
}
for(e : bean.exportExposes){
var expose = e
var segments = <String>newArrayList()
segments.add(expose.refEntity.name)
while(expose.refProperty === null){
expose = expose.subExpose
segments.add(expose.refEntity.name)
}
var pathToProperty = segments.join(".")
tmpList.add(encodeFreemarker('''«rootEntityName».«pathToProperty»''', expose.refProperty, paths, quote, false, -1, ""))
fldList.add(expose.refProperty.name)
}
var body = '''
«fldList.join(delimiter)»
<#list vector as «rootEntityName»>
«tmpList.join(delimiter)»
</#list>'''
return body
}
def String createFixedTemplate(String rootEntityName, List<LFeature> fieldList, EList<DataInterchangeBean> paths) {
var tmpList = <String>newArrayList()
for(path:paths) {
for(map:path.mappings) {
var column = map as DataInterchangeFixedColumnMapping
tmpList.add(encodeFreemarker(rootEntityName, column.property, paths, null, false, column.length, null))
}
}
var body = '''
<#list vector as «rootEntityName»>
«tmpList.join()»
</#list>'''
return body
}
def String encodeFreemarker(String entityName, LFeature field, EList<DataInterchangeBean> paths, String quote, boolean encodeHtml, int length, String beanPrefix) {
var format = null as DataInterchangeFormat
var LEntity entity = null
if(field.eContainer instanceof LEntity) {
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, encodeHtml, length, beanPrefix, null)
}
def String encodeFreemarker(String entityName, LFeature field, DataInterchangeFormat format, String quote, boolean encodeHtml, int length, String beanPrefix, List<String> segments) {
var EType etype = null
var String fldName = null
var template = ""
if(field instanceof LEntityAttribute) {
fldName = '''«entityName».«field.toName»'''
etype = dtType.getBasicType(field)
}
if(field instanceof LBeanAttribute) {
fldName = '''«entityName».«beanPrefix».«field.toName»'''
etype = dtType.getBasicType(field)
}
if(field instanceof LEntityAttribute || field instanceof LBeanAttribute) {
if (etype == EType.BOOLEAN) {
template = '''${(«fldName»?c«fixedLength(length)»)!«fixedLength(length)»}'''
return if(segments !== null) encodeFreeMarkerForExpose(entityName, segments, template, null, null) else template
}
else if (format !== null) {
template = '''${(«fldName»?string["«format.format»"]«fixedLength(length)»)!«fixedLength(length)»}'''
return if(segments !== null) encodeFreeMarkerForExpose(entityName, segments, template, null, null) else template
}
else if (etype == EType.DATE || etype == EType.TIMESTAMP) {
template = '''${(«fldName»?datetime?iso_local_ms_nz)«fixedLength(length)»!«fixedLength(length)»}'''
return if(segments !== null) encodeFreeMarkerForExpose(entityName, segments, template, null, null) else template
}
else if (etype == EType.STRING) {
template = '''«quote»${(«fldName»«IF encodeHtml»?html«ENDIF»«fixedLength(length)»)!«fixedLength(length)»}«quote»'''
return if(segments !== null) encodeFreeMarkerForExpose(entityName, segments, template, null, null) else template
}
else {
template = '''${(«fldName»)«fixedLength(length)»!«fixedLength(length)»}'''
return if(segments !== null) encodeFreeMarkerForExpose(entityName, segments, template, null, null) else template
}
}
if(field instanceof LEntityReference) {
etype = dtType.getBasicType((field as LEntityReference).type.primaryKeyAttribute)
if (etype == EType.STRING) {
template = '''«quote»${(«entityName».«field.toName».«(field as LEntityReference).type.primaryKeyAttribute.name»«fixedLength(length)»)!«fixedLength(length)»}«quote»'''
return if(segments !== null) encodeFreeMarkerForExpose(entityName, segments, template, null, null) else template
} else {
template = '''${(«entityName».«field.toName».«(field as LEntityReference).type.primaryKeyAttribute.name»«fixedLength(length)»)!«fixedLength(length)»}'''
return if(segments !== null) encodeFreeMarkerForExpose(entityName, segments, template, null, null) else template
}
}
}
def String encodeFreeMarkerForExpose(String entityName, List<String> segments, String fieldexpression, String prefix, String sufix){
var part = entityName.substring(0, entityName.indexOf("."))
var part1 = ""
var part2 = ""
if(segments === null || (segments.get(0) !== null && segments.get(0).isEmpty)){
return fieldexpression
}
else{
for(String segment : segments){
part = '''«part».«segment»'''
part1 = part1.concat('''<#if «part»?exists>''')
part2 = part2.concat('''</#if>''')
}
}
return part1.concat(fieldexpression).concat(part2)
}
def fixedLength(int length)
'''«IF length > 0»?right_pad(«length»)[0..*«length»]«ENDIF»'''
/* 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, int paramCnt) {
var pCnt = paramCnt
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«pCnt++»'''
whereList.add(qstr)
if(lookup.condition !== null) {
var lstr = '''x«aliasCnt».«lookup.condition.refProperty.toName» «lookup.condition.operator» «IF lookup.condition.operand instanceof DataInterchangeLookupFilterOperandString»'«(lookup.condition.operand as DataInterchangeLookupFilterOperandString).value»'«ELSE»:param«pCnt++»«ENDIF»'''
if(lookup.condition.subcondition !== null) {
lstr = lstr + " " + lookup.condition.operator2.literal + " "
lstr = lookup.condition.subcondition.iterateCondition(lstr, aliasCnt, pCnt)
}
whereList.add("("+lstr+")")
}
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 ")»'''
}
def String iterateCondition(DataInterchangeLookupFilterCondition condition, String input, int aliasCnt, int paramCnt) {
var pCnt = paramCnt
var lstr = '''«input»x«aliasCnt».«condition.refProperty.toName» «condition.operator» «IF condition.operand instanceof DataInterchangeLookupFilterOperandString»'«(condition.operand as DataInterchangeLookupFilterOperandString).value»'«ELSEIF !condition.operator.literal.startsWith("is")»:param«pCnt++»«ENDIF»'''
if(condition.subcondition !== null) {
lstr = lstr + " " + condition.operator2.literal + " "
lstr = condition.subcondition.iterateCondition(lstr, aliasCnt, pCnt)
}
return lstr
}
def void iterateConditionParameter(DataInterchangeLookupFilterCondition condition, Document doc, Element locator, EList<DataInterchangeMapping> mappings, String autoMapping, int paramCnt, boolean byAttribute) {
var pCnt = paramCnt
if(condition.operand instanceof DataInterchangeLookupFilterOperandProperty && !condition.operator.literal.startsWith("is")) {
var prop = (condition.operand as DataInterchangeLookupFilterOperandProperty).refProperty
for(mapping:mappings) {
if(mapping instanceof DataInterchangePropertyMapping) {
if(mapping.property.equals(prop)) {
if(mapping.data === null) {
createDaoParam(doc, locator, '''param«paramCnt»''', prop.type.name.toFirstUpper, autoMapping, prop.toName, byAttribute)
} else {
createDaoParam(doc, locator, '''param«paramCnt»''', prop.type.name.toFirstUpper, mapping.data, prop.toName, byAttribute)
}
pCnt ++
}
}
}
}
if(condition.subcondition !== null) {
condition.subcondition.iterateConditionParameter(doc, locator, mappings, autoMapping, pCnt, byAttribute)
}
}
def String queryKeys(DataInterchangeBean bean) {
var pCnt = 0
var eCnt = -1
var LEntity oldEntity = null
var select = '''«bean.entity.toName» x«pCnt»'''
var rootAlias = '''x«pCnt»'''
var whereList = <String>newArrayList
for(key:bean.lookupKeys) {
if(key.property.eContainer.equals(bean.entity)) {
if(!key.property.eContainer.equals(oldEntity)) {
eCnt ++
oldEntity = key.property.eContainer as LEntity
}
var qstr = '''x«eCnt».«key.property.toName» = :param«pCnt»'''
whereList.add(qstr)
} else {
for(lookup:bean.lookup) {
if(lookup.queryProperty.equals(key.property)) {
if(!lookup.queryProperty.equals(oldEntity)) {
eCnt ++
oldEntity = lookup.queryProperty as LEntity
}
select = '''«select» left join «lookup.entity.toName» x«pCnt» on(x«pCnt»=«rootAlias».«lookup.targetProperty.toName»)'''
var qstr = '''x«eCnt».«key.property.toName» = :param«pCnt»'''
whereList.add(qstr)
}
}
}
pCnt ++;
}
return '''from «select» where «whereList.join(" and ")»'''
}
def String queryVersion(DataInterchangeBean bean) {
var select = '''«bean.entity.toName» x'''
var qstr = '''x.«bean.entity.idAttributeName» = :param'''
return '''from «select» where «qstr»'''
}
def boolean containsFeature(List<DataInterchangeExportHide> list, LFeature f){
for(exclude : list){
if(exclude.property.equals(f)){
return true
}
}
return false
}
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
, IDataInterchange
, StreamSource
, URL
, URI
, InputStream
, StreamUtils
, MalformedURLException
, FileAlreadyExistsException
, URISyntaxException
, EntityManager
, 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
, CriteriaBuilder
, CriteriaQuery
, Root
, TypedQuery
, JoinType
, Paths
, Path
, Files
, StandardOpenOption
, BufferedOutputStream
, BufferedInputStream
, UI
, Pair
, IEntityImportInitializationListener
, ConstraintViolationException
, ConstraintViolation
, EventDispatcherEvent
, EventDispatcherCommand
, TransformerConfigurationException
, SAXException
, IOException
, UUID
, IOException
, File
, FileInputStream
, Properties
, ProductConfiguration
, PrintWriter
, BlobService
, BlobTypingAPI
, Component
, Panel
, Paths
, Date
, Metamodel
, EntityType
, ListJoin
, Join
)
super.createAppendable(context, importManager, config)
}
}