blob: 6ae321dd326bc381d25e5902e2d27d095666fd06 [file] [log] [blame]
/*
* Copyright (c) 2010-2021 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
*/
package org.eclipse.scout.sdk.core.s.page;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.eclipse.scout.sdk.core.builder.java.comment.IJavaElementCommentBuilder;
import org.eclipse.scout.sdk.core.generator.method.IMethodGenerator;
import org.eclipse.scout.sdk.core.generator.method.MethodGenerator;
import org.eclipse.scout.sdk.core.generator.methodparam.MethodParameterGenerator;
import org.eclipse.scout.sdk.core.generator.type.PrimaryTypeGenerator;
import org.eclipse.scout.sdk.core.model.api.Flags;
import org.eclipse.scout.sdk.core.model.api.IClasspathEntry;
import org.eclipse.scout.sdk.core.model.api.IType;
import org.eclipse.scout.sdk.core.s.ISdkConstants;
import org.eclipse.scout.sdk.core.s.apidef.IScoutApi;
import org.eclipse.scout.sdk.core.s.classid.ClassIds;
import org.eclipse.scout.sdk.core.s.dto.DtoGeneratorFactory;
import org.eclipse.scout.sdk.core.s.environment.IEnvironment;
import org.eclipse.scout.sdk.core.s.environment.IFuture;
import org.eclipse.scout.sdk.core.s.environment.IProgress;
import org.eclipse.scout.sdk.core.s.service.ServiceNewOperation;
import org.eclipse.scout.sdk.core.s.util.ScoutTier;
import org.eclipse.scout.sdk.core.util.Ensure;
import org.eclipse.scout.sdk.core.util.FinalValue;
import org.eclipse.scout.sdk.core.util.JavaTypes;
import org.eclipse.scout.sdk.core.util.Strings;
/**
* <h3>{@link PageNewOperation}</h3>
*
* @since 7.0.0
*/
public class PageNewOperation implements BiConsumer<IEnvironment, IProgress> {
// in
private String m_pageName;
private FinalValue<String> m_baseName = new FinalValue<>();
private IClasspathEntry m_clientSourceFolder;
private IClasspathEntry m_pageDataSourceFolder;
private IClasspathEntry m_sharedSourceFolder;
private IClasspathEntry m_serverSourceFolder;
private IClasspathEntry m_testSourceFolder;
private String m_package;
private String m_superType;
private String m_serverSession;
private boolean m_createAbstractPage;
private boolean m_pageWithTable;
private boolean m_createPageData;
private boolean m_createOrAppendService;
private ServiceNewOperation m_serviceNewOperation; // optional
// out
private IFuture<IType> m_createdAbstractPage;
private String m_createdAbstractPageFqn;
private IFuture<IType> m_createdPage;
private String m_createdPageFqn;
private IFuture<IType> m_createdPageData;
private String m_createdPageDataFqn;
private IFuture<IType> m_createdAbstractPageData;
private String m_createdAbstractPageDataFqn;
private IFuture<IType> m_createdServiceIfc;
private String m_serviceIfcFqn;
private IFuture<IType> m_createdServiceImpl;
private String m_serviceImplFqn;
private IFuture<IType> m_createdServiceTest;
private String m_serviceTestFqn;
private String m_dataFetchMethodName;
@Override
public void accept(IEnvironment env, IProgress progress) {
validateOperation();
prepareOperation();
prepareProgress(progress);
executeOperation(env, progress);
}
protected void validateOperation() {
Ensure.notBlank(getPageName(), "No page name provided");
Ensure.notNull(getClientSourceFolder(), "No client source folder provided");
Ensure.notBlank(getPackage(), "No package name provided");
Ensure.notNull(getSuperType(), "No supertype provided");
}
protected void prepareOperation() {
setPageWithTable(calculatePageWithTable());
setCreatePageData(isPageWithTable() && getPageDataSourceFolder() != null);
setCreateOrAppendService(isCreatePageData() && getSharedSourceFolder() != null && getServerSourceFolder() != null);
}
protected void prepareProgress(IProgress progress) {
progress.init(getTotalWork(), toString());
}
protected void executeOperation(IEnvironment env, IProgress progress) {
var sharedPackage = ScoutTier.Client.convert(ScoutTier.Shared, getPackage());
if (isCreatePageData()) {
if (isCreateAbstractPage()) {
setCreatedAbstractPageData(createPageData(ISdkConstants.PREFIX_ABSTRACT + getPageName(), sharedPackage, this::setCreatedAbstractPageDataFqn, env, progress.newChild(1)));
}
setCreatedPageData(createPageData(getPageName(), sharedPackage, this::setCreatedPageDataFqn, env, progress.newChild(1)));
}
if (isCreateOrAppendService()) {
createOrAppendService(sharedPackage, env, progress);
}
if (isCreateAbstractPage()) {
setCreatedAbstractPage(createAbstractPage(isPageWithTable(), env, progress.newChild(1)));
setSuperType(getCreatedAbstractPageFqn());
}
setCreatedPage(createPage(isPageWithTable(), env, progress.newChild(1)));
// run DTO update because the pageData has been created as empty java file
if (isCreatePageData()) {
updatePageDatas(env, progress.newChild(2));
}
}
protected int getTotalWork() {
var result = 1; // page
if (isCreateAbstractPage()) {
result += 1;// abstract page
}
if (isCreatePageData()) {
if (isCreateAbstractPage()) {
result += 1; // abstract pageData
}
result += 1; // pageData
result += 2; // update pageDatas
}
if (isCreateService()) {
result += 3;// ifc, impl, test
}
return result;
}
protected boolean calculatePageWithTable() {
return getClientSourceFolder()
.javaEnvironment()
.findType(JavaTypes.erasure(getSuperType()))
.map(PageNewOperation::calculatePageWithTable)
.orElse(false);
}
protected static boolean calculatePageWithTable(IType type) {
var scoutApi = type.javaEnvironment().requireApi(IScoutApi.class);
return type.isInstanceOf(scoutApi.IPageWithTable());
}
protected void updatePageDatas(IEnvironment env, IProgress progress) {
if (isCreateAbstractPage()) {
// the DtoGeneratorFactory parses the @Data-Annotation and uses the given pageData-IType, therefore the pageData needs to be created already
getCreatedAbstractPageData().result();
var abstractPageDataGenerator = DtoGeneratorFactory.createPageDataGenerator(getCreatedAbstractPage().result(), getPageDataSourceFolder().javaEnvironment());
env.writeCompilationUnitAsync(abstractPageDataGenerator.get(), getPageDataSourceFolder(), progress.newChild(1));
}
// the DtoGeneratorFactory parses the @Data-Annotation and uses the given pageData-IType, therefore the pageData needs to be created already
getCreatedPageData().result();
var pageDataGenerator = DtoGeneratorFactory.createPageDataGenerator(getCreatedPage().result(), getPageDataSourceFolder().javaEnvironment());
env.writeCompilationUnitAsync(pageDataGenerator.get(), getPageDataSourceFolder(), progress.newChild(1));
}
protected IFuture<IType> createAbstractPage(boolean isPageWithTable, IEnvironment env, IProgress progress) {
var pageBuilder = createPageBuilder(isPageWithTable, true);
setCreatedAbstractPageFqn(pageBuilder.fullyQualifiedName());
return env.writeCompilationUnitAsync(pageBuilder, getClientSourceFolder(), progress);
}
protected String getBaseName() {
return m_baseName.computeIfAbsentAndGet(this::calcPageBaseName);
}
protected String calcPageBaseName() {
var name = getPageName();
String[] suffixes = {ISdkConstants.SUFFIX_PAGE_WITH_NODES, ISdkConstants.SUFFIX_PAGE_WITH_TABLE, ISdkConstants.SUFFIX_OUTLINE_PAGE};
for (var suffix : suffixes) {
var suffixLen = suffix.length();
var strOffset = name.length() - suffixLen;
if (name.regionMatches(true, strOffset, suffix, 0, suffixLen)) {
name = name.substring(0, name.length() - suffixLen);
}
}
return name;
}
public String getServiceBaseName() {
return getBaseName();
}
protected String getServiceMethodName() {
var name = getBaseName();
return "get" + name + "TableData";
}
protected void createOrAppendService(String sharedPackage, IEnvironment env, IProgress progress) {
if (isCreateService()) {
createService(sharedPackage, getServiceBaseName(), env, progress.newChild(3));
}
else if (isAppendService()) {
var op = getServiceNewOperation();
addServiceMethods(op);
var svcName = op.getServiceName() + ISdkConstants.SUFFIX_SERVICE;
var serverPackage = ScoutTier.Shared.convert(ScoutTier.Server, op.getSharedPackage());
setServiceIfcFqn(sharedPackage + JavaTypes.C_DOT + "I" + svcName);
setServiceImplFqn(serverPackage + JavaTypes.C_DOT + svcName);
if (op.isCreateTest()) {
setServiceTestFqn(getServiceImplFqn() + ISdkConstants.SUFFIX_TEST);
}
}
}
protected void createService(String sharedPackage, String baseName, IEnvironment env, IProgress progress) {
var serviceNewOperation = createServiceOperation();
prepareServiceOperation(serviceNewOperation, sharedPackage, baseName);
addServiceMethods(serviceNewOperation);
serviceNewOperation.accept(env, progress);
setCreatedServiceImpl(serviceNewOperation.getCreatedServiceImpl());
setServiceImplFqn(serviceNewOperation.getCreatedServiceImplFqn());
setCreatedServiceIfc(serviceNewOperation.getCreatedServiceInterface());
setServiceIfcFqn(serviceNewOperation.getCreatedServiceInterfaceFqn());
setCreatedServiceTest(serviceNewOperation.getCreatedServiceTest());
setServiceTestFqn(serviceNewOperation.getCreatedServiceTestFqn());
}
protected void addServiceMethods(ServiceNewOperation serviceNewOperation) {
serviceNewOperation.addMethod(createServiceMethod());
}
protected IMethodGenerator<?, ?> createServiceMethod() {
setDataFetchMethodName(getServiceMethodName());
return MethodGenerator.create()
.asPublic()
.withReturnType(getCreatedPageDataFqn())
.withElementName(getDataFetchMethodName())
.withParameter(MethodParameterGenerator.create()
.withElementName("filter")
.withDataTypeFrom(IScoutApi.class, api -> api.SearchFilter().fqn()))
.withComment(IJavaElementCommentBuilder::appendDefaultElementComment)
.withBody(b -> {
var varName = "pageData";
b.ref(getCreatedPageDataFqn()).space().append(varName).equalSign().appendNew().ref(getCreatedPageDataFqn()).parenthesisOpen().parenthesisClose().semicolon().nl()
.appendTodo("fill " + varName + '.')
.returnClause().append(varName).semicolon();
});
}
protected ServiceNewOperation createServiceOperation() {
return new ServiceNewOperation();
}
protected void prepareServiceOperation(ServiceNewOperation serviceNewOperation, String sharedPackage, String baseName) {
serviceNewOperation.setServiceName(baseName);
serviceNewOperation.setSharedPackage(sharedPackage);
serviceNewOperation.setSharedSourceFolder(getSharedSourceFolder());
serviceNewOperation.setServerSourceFolder(getServerSourceFolder());
if (getTestSourceFolder() == null) {
return;
}
serviceNewOperation.setTestSourceFolder(getTestSourceFolder());
serviceNewOperation.setServerSession(getServerSession());
serviceNewOperation.setCreateTest(true);
}
protected PageGenerator<?> createPageBuilder(boolean isPageWithTable, boolean isAbstractPage) {
var generator = createPageGenerator();
preparePageGenerator(generator, isPageWithTable, isAbstractPage);
return generator;
}
protected PageGenerator<?> createPageGenerator() {
return new PageGenerator<>();
}
protected void preparePageGenerator(PageGenerator<?> generator, boolean isPageWithTable, boolean isAbstractPage) {
var name = getPageName();
if (isAbstractPage) {
name = ISdkConstants.PREFIX_ABSTRACT + name;
}
var fqn = getPackage() + JavaTypes.C_DOT + name;
generator
.withElementName(name)
.withPackageName(getPackage())
.withFlags(isAbstractPage ? Flags.AccAbstract : Flags.AccPublic)
.withNlsMethod(isCreateAbstractPage() == isAbstractPage)
.withLeafMethod(isPageWithTable && isCreateAbstractPage() == isAbstractPage)
.withClassIdValue(ClassIds.nextIfEnabled(fqn))
.withTableClassIdValue(ClassIds.nextIfEnabled(fqn))
.withDataFetchMethodName(getDataFetchMethodName())
.asPageWithTable(isPageWithTable)
.withSuperClass(getSuperType());
var dtoFqn = getCreatedPageDataFqn();
if (isAbstractPage) {
dtoFqn = getCreatedAbstractPageDataFqn();
}
generator.withPageData(dtoFqn);
if (!isAbstractPage && Strings.hasText(getServiceIfcFqn())) {
generator.withPageServiceInterface(getServiceIfcFqn());
}
}
protected IFuture<IType> createPage(boolean isPageWithTable, IEnvironment env, IProgress progress) {
var pageBuilder = createPageBuilder(isPageWithTable, false);
if (isCreateAbstractPage() && isPageWithTable) {
var superTypeFqn = getCreatedAbstractPageFqn()
+ JavaTypes.C_GENERIC_START
+ pageBuilder.fullyQualifiedName()
+ JavaTypes.C_DOLLAR
+ PageGenerator.INNER_TABLE_NAME
+ JavaTypes.C_GENERIC_END
+ JavaTypes.C_DOT
+ PageGenerator.INNER_TABLE_NAME;
pageBuilder.withTableSuperType(superTypeFqn);
}
setCreatedPageFqn(pageBuilder.fullyQualifiedName());
return env.writeCompilationUnitAsync(pageBuilder, getClientSourceFolder(), progress);
}
protected IFuture<IType> createPageData(String pageName, String sharedPackage, Consumer<String> fqnConsumer, IEnvironment env, IProgress progress) {
var pageDataGenerator = PrimaryTypeGenerator.create()
.withElementName(pageName + ISdkConstants.SUFFIX_DTO)
.withPackageName(sharedPackage)
.asPublic()
.withSuperClassFrom(IScoutApi.class, api -> api.AbstractTablePageData().fqn());
if (fqnConsumer != null) {
fqnConsumer.accept(pageDataGenerator.fullyQualifiedName());
}
return env.writeCompilationUnitAsync(pageDataGenerator, getPageDataSourceFolder(), progress);
}
public IFuture<IType> getCreatedPage() {
return m_createdPage;
}
protected void setCreatedPage(IFuture<IType> page) {
m_createdPage = page;
}
public String getCreatedPageFqn() {
return m_createdPageFqn;
}
protected void setCreatedPageFqn(String createdPageFqn) {
m_createdPageFqn = createdPageFqn;
}
public String getPageName() {
return m_pageName;
}
public void setPageName(String pageName) {
m_baseName = new FinalValue<>();
m_pageName = pageName;
}
public IClasspathEntry getClientSourceFolder() {
return m_clientSourceFolder;
}
public void setClientSourceFolder(IClasspathEntry clientSourceFolder) {
m_clientSourceFolder = clientSourceFolder;
}
public String getPackage() {
return m_package;
}
public void setPackage(String package1) {
m_package = package1;
}
public String getSuperType() {
return m_superType;
}
public void setSuperType(String superType) {
m_superType = superType;
}
public IClasspathEntry getSharedSourceFolder() {
return m_sharedSourceFolder;
}
public void setSharedSourceFolder(IClasspathEntry sharedSourceFolder) {
m_sharedSourceFolder = sharedSourceFolder;
}
public IFuture<IType> getCreatedPageData() {
return m_createdPageData;
}
protected void setCreatedPageData(IFuture<IType> createdPageData) {
m_createdPageData = createdPageData;
}
public String getCreatedPageDataFqn() {
return m_createdPageDataFqn;
}
protected void setCreatedPageDataFqn(String createdPageDataFqn) {
m_createdPageDataFqn = createdPageDataFqn;
}
public IClasspathEntry getServerSourceFolder() {
return m_serverSourceFolder;
}
public void setServerSourceFolder(IClasspathEntry serverSourceFolder) {
m_serverSourceFolder = serverSourceFolder;
}
public IFuture<IType> getCreatedServiceIfc() {
return m_createdServiceIfc;
}
protected void setCreatedServiceIfc(IFuture<IType> createdServiceIfc) {
m_createdServiceIfc = createdServiceIfc;
}
public String getServiceIfcFqn() {
return m_serviceIfcFqn;
}
protected void setServiceIfcFqn(String serviceIfcFqn) {
m_serviceIfcFqn = serviceIfcFqn;
}
public IFuture<IType> getCreatedServiceImpl() {
return m_createdServiceImpl;
}
protected void setCreatedServiceImpl(IFuture<IType> createdServiceImpl) {
m_createdServiceImpl = createdServiceImpl;
}
public String getServiceImplFqn() {
return m_serviceImplFqn;
}
protected void setServiceImplFqn(String serviceImplFqn) {
m_serviceImplFqn = serviceImplFqn;
}
public IClasspathEntry getPageDataSourceFolder() {
return m_pageDataSourceFolder;
}
public void setPageDataSourceFolder(IClasspathEntry pageDataSourceFolder) {
m_pageDataSourceFolder = pageDataSourceFolder;
}
public IClasspathEntry getTestSourceFolder() {
return m_testSourceFolder;
}
public void setTestSourceFolder(IClasspathEntry testSourceFolder) {
m_testSourceFolder = testSourceFolder;
}
public IFuture<IType> getCreatedServiceTest() {
return m_createdServiceTest;
}
protected void setCreatedServiceTest(IFuture<IType> createdServiceTest) {
m_createdServiceTest = createdServiceTest;
}
public String getServiceTestFqn() {
return m_serviceTestFqn;
}
protected void setServiceTestFqn(String serviceTestFqn) {
m_serviceTestFqn = serviceTestFqn;
}
protected String getDataFetchMethodName() {
return m_dataFetchMethodName;
}
protected void setDataFetchMethodName(String dataFetchMethodName) {
m_dataFetchMethodName = dataFetchMethodName;
}
public boolean isCreateAbstractPage() {
return m_createAbstractPage;
}
public void setCreateAbstractPage(boolean createAbstractPage) {
m_createAbstractPage = createAbstractPage;
}
public boolean isPageWithTable() {
return m_pageWithTable;
}
protected void setPageWithTable(boolean pageWithTable) {
m_pageWithTable = pageWithTable;
}
public boolean isCreatePageData() {
return m_createPageData;
}
protected void setCreatePageData(boolean createPageData) {
m_createPageData = createPageData;
}
public boolean isCreateOrAppendService() {
return m_createOrAppendService;
}
protected void setCreateOrAppendService(boolean createOrAppendService) {
m_createOrAppendService = createOrAppendService;
}
public boolean isCreateService() {
return isCreateOrAppendService() && getServiceNewOperation() == null;
}
public boolean isAppendService() {
return isCreateOrAppendService() && getServiceNewOperation() != null;
}
public ServiceNewOperation getServiceNewOperation() {
return m_serviceNewOperation;
}
public void setServiceNewOperation(ServiceNewOperation serviceNewOperation) {
m_serviceNewOperation = serviceNewOperation;
}
public IFuture<IType> getCreatedAbstractPage() {
return m_createdAbstractPage;
}
protected void setCreatedAbstractPage(IFuture<IType> createdAbstractPage) {
m_createdAbstractPage = createdAbstractPage;
}
public String getCreatedAbstractPageFqn() {
return m_createdAbstractPageFqn;
}
protected void setCreatedAbstractPageFqn(String createdAbstractPageFqn) {
m_createdAbstractPageFqn = createdAbstractPageFqn;
}
public IFuture<IType> getCreatedAbstractPageData() {
return m_createdAbstractPageData;
}
protected void setCreatedAbstractPageData(IFuture<IType> createdAbstractPageData) {
m_createdAbstractPageData = createdAbstractPageData;
}
public String getCreatedAbstractPageDataFqn() {
return m_createdAbstractPageDataFqn;
}
protected void setCreatedAbstractPageDataFqn(String createdAbstractPageDataFqn) {
m_createdAbstractPageDataFqn = createdAbstractPageDataFqn;
}
public String getServerSession() {
return m_serverSession;
}
public void setServerSession(String serverSession) {
m_serverSession = serverSession;
}
@Override
public String toString() {
return "Create new Page";
}
}