blob: e235edb4e739126a0217dc4cd73ef28a9e4c065e [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), 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:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.dsl.services.xtext.jvmmodel
import com.google.inject.Inject
import java.util.Set
import javax.persistence.EntityManagerFactory
import org.eclipse.emf.ecore.EObject
import org.eclipse.osbp.dsl.common.xtext.extensions.NamingExtensions
import org.eclipse.osbp.dsl.dto.lib.services.impl.AbstractDTOService
import org.eclipse.osbp.dsl.dto.lib.services.impl.AbstractDTOServiceWithMutablePersistence
import org.eclipse.osbp.dsl.dto.xtext.extensions.MethodNamingExtensions
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage
import org.eclipse.osbp.dsl.semantic.service.LCardinality
import org.eclipse.osbp.dsl.semantic.service.LDTOService
import org.eclipse.osbp.dsl.semantic.service.LInjectedService
import org.eclipse.osbp.dsl.semantic.service.OSBPServiceFactory
import org.eclipse.osbp.dsl.services.xtext.extensions.ModelExtensions
import org.eclipse.osbp.dsl.services.xtext.extensions.ServicesTypesBuilder
import org.eclipse.osbp.xtext.oxtype.logger.TimeLogger
import org.eclipse.osbp.xtext.oxtype.resource.ExtendedModelInferrer
import org.eclipse.xtext.common.types.JvmGenericType
import org.eclipse.xtext.common.types.JvmType
import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.slf4j.Logger
import org.slf4j.LoggerFactory
/**
* <p>Infers a JVM model from the source model.</p>
*
* <p>The JVM model should contain all elements that would appear in the Java code
* which is generated from the source model. Other models link against the JVM model rather than the source model.</p>
*/
class ServicesGrammarJvmModelInferrer extends ExtendedModelInferrer {
/**
* convenience API to build and initialize JVM types and their members.
*/
protected val Logger log = LoggerFactory.getLogger(getClass())
@Inject extension IQualifiedNameProvider
@Inject extension ServicesTypesBuilder
@Inject extension ModelExtensions
@Inject extension NamingExtensions
@Inject TypeReferences references
@Inject
private MethodNamingExtensions dtoNamings;
def dispatch void inferFullState(JvmType type, EObject element, IJvmDeclaredTypeAcceptor acceptor,
boolean isPrelinkingPhase, String selector) {
}
// used for test cases with old derived state computer
def dispatch void infer(LDTOService service, IJvmDeclaredTypeAcceptor acceptor, boolean isPrelinkingPhase) {
val type = service.toJvmType;
type.inferFullState(service, acceptor, isPrelinkingPhase, "")
}
def dispatch void inferTypesOnly(LDTOService service, IJvmDeclaredTypeAcceptor acceptor, boolean isPrelinkingPhase) {
val type = service.toJvmType
acceptor.accept(type);
// pass inferring to delegates
inferTypesOnlyByDelegates(service, acceptor, isPrelinkingPhase);
}
def dispatch void inferFullState(JvmGenericType type, LDTOService service, IJvmDeclaredTypeAcceptor acceptor,
boolean isPrelinkingPhase, String selector) {
acceptor.accept(type).initializeLater [
val TimeLogger doInferLog = TimeLogger.start(getClass());
fileHeader = (service.eContainer as LTypedPackage).documentation
documentation = service.getDocumentation
if (service.dto.basedOnEntity) {
if (service.mutablePersistenceId) {
superTypes += references.getTypeForName(typeof(AbstractDTOServiceWithMutablePersistence), service,
service.dto.toTypeReference, service.dto.wrappedEntity.toTypeReference)
} else {
superTypes += references.getTypeForName(typeof(AbstractDTOService), service,
service.dto.toTypeReference, service.dto.wrappedEntity.toTypeReference)
}
// Constructor
if (service.mutablePersistenceId) {
members += service.toConstructor() [
body = '''
// set the default persistence ID
setPersistenceId("«service.persistenceId»");'''
]
} else {
members += service.toConstructor()[]
}
if (service.dtoJvm !== null) {
members += service.toMethod("getDtoClass",
references.getTypeForName(typeof(Class), service, service.dtoJvm.cloneWithProxies)) [
body = '''return «service.dto.name».class;'''
]
}
members += service.toMethod("getEntityClass",
references.getTypeForName(typeof(Class), service, service.dto.wrappedType.toTypeReference)) [
body = '''return «service.dto.wrappedEntity.name».class;'''
]
if (service.dto.idAttribute !== null) {
members += service.toMethod("getId", references.getTypeForName(typeof(Object), service, null)) [
parameters += service.toParameter('dto', service.dto.toTypeReference)
body = '''return dto.«service.dto.idAttribute?.toGetterName»();'''
]
} else {
if (service.dtoJvm !== null) {
members += service.toMethod("getId", references.getTypeForName(typeof(Object), service, null)) [
parameters += service.toParameter('dto', service.dtoJvm.cloneWithProxies)
body = '''throw new UnsupportedOperationException("No id available for DTO.");'''
]
}
}
for (f : service.operations) {
members += f.toMethod(f.toName, f.getType) [
documentation = f.getDocumentation
for (p : f.getParams) {
parameters += p.toParameter(p.name, p.parameterType)
}
body = f.getBody
]
}
} else {
// Constructor
members += service.toConstructor()[]
// create the emf service
val LInjectedService emfService = OSBPServiceFactory.eINSTANCE.createLInjectedService
emfService.attributeName = "emf"
emfService.cardinality = LCardinality.ONE_TO_ONE
emfService.service = references.getTypeForName(typeof(EntityManagerFactory), service, null)
service.injectedServices.services += emfService
if (service.injectedServices !== null) {
for (f : service.injectedServices.services) {
switch (f.cardinality) {
case ZERO_TO_ONE:
members += f.toField(f.attributeName, f.service.cloneWithProxies)
case ZERO_TO_MANY:
members += f.toField(f.attributeName,
references.getTypeForName(typeof(Set), service, f.service.cloneWithProxies))
case ONE_TO_ONE:
members += f.toField(f.attributeName, f.service.cloneWithProxies)
case ONE_TO_MANY:
members += f.toField(f.attributeName,
references.getTypeForName(typeof(Set), service, f.service.cloneWithProxies))
default:
members += f.toField(f.attributeName, f.service.cloneWithProxies)
}
}
}
//
for (f : service.operations) {
members += f.toMethod(f.toName, f.getType) [
documentation = f.getDocumentation
for (p : f.getParams) {
parameters += p.toParameter(p.name, p.parameterType)
}
body = f.getBody
]
}
// other services
if (service.injectedServices !== null) {
for (f : service.injectedServices.services) {
switch (f.cardinality) {
case ZERO_TO_ONE: {
members += f.toBindService(f.attributeName, f.service.cloneWithProxies)
members += f.toUnbindService(f.attributeName, f.service.cloneWithProxies)
}
case ONE_TO_ONE: {
members += f.toBindService(f.attributeName, f.service.cloneWithProxies)
members += f.toUnbindService(f.attributeName, f.service.cloneWithProxies)
}
case ZERO_TO_MANY: {
members += f.toAddService(f.attributeName, f.service.cloneWithProxies)
members += f.toRemoveService(f.attributeName, f.service.cloneWithProxies)
}
case ONE_TO_MANY: {
members += f.toAddService(f.attributeName, f.service.cloneWithProxies)
members += f.toRemoveService(f.attributeName, f.service.cloneWithProxies)
}
}
}
}
}
doInferLog.stop(log, "Inferring service " + service.name)
]
}
}