| /** |
| * 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) |
| ] |
| |
| } |
| } |