diff --git a/myapp/.gitignore b/myapp/.gitignore new file mode 100644 index 0000000..1b64d26 --- /dev/null +++ b/myapp/.gitignore @@ -0,0 +1,21 @@ +.* +!.github +!.gitignore +!.mvn +!.travis.yml +*.bak +*.log +*.class +*.diff +*.patch +*.iml +*.jar +*.war +*.ear +hs_err_pid* + +target +eclipse-target +war +**/src/generated/ +**/tmp/ diff --git a/myapp/.mvn/maven.config b/myapp/.mvn/maven.config new file mode 100644 index 0000000..009da89 --- /dev/null +++ b/myapp/.mvn/maven.config @@ -0,0 +1 @@ +-Drevision=1.0.0-SNAPSHOT diff --git a/myapp/OpenApi.yaml b/myapp/OpenApi.yaml new file mode 100644 index 0000000..d014759 --- /dev/null +++ b/myapp/OpenApi.yaml @@ -0,0 +1,60 @@ +openapi: 3.0.1 +info: + title: CounterApiExample + description: This is just an example of the counter app + version: "1.1.1" + x-rootpackage: "com.flutter" +paths: + /counter: + x-component: countermanagement + get: + tags: + - CounterService + description: "Get the current value of the counter" + operationId: getCounter + responses: + "200": + description: "the counter's current value" + content: + application/json: + schema: + $ref: "#/components/schemas/Counter" + delete: + tags: + - CounterService + description: "Reset the counter" + operationId: resetCounter + responses: + "200": + description: "the counter's current value" + content: + application/json: + schema: + $ref: "#/components/schemas/Counter" + post: + tags: + - CounterService + description: "Increase the current value of the counter by an amount" + operationId: incCounter + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Counter" + responses: + "200": + description: "the counters current value" + content: + application/json: + schema: + $ref: "#/components/schemas/Counter" +components: + schemas: + Counter: + x-component: counter + required: + - amount + properties: + amount: + type: integer \ No newline at end of file diff --git a/myapp/api/pom.xml b/myapp/api/pom.xml new file mode 100644 index 0000000..593437d --- /dev/null +++ b/myapp/api/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + com.example.domain + myapp + ${revision} + + myapp-api + jar + ${project.artifactId} + API of the server for the myapp application (containing datatypes, transfer-objects, and service interfaces). + + + + org.springframework.data + spring-data-commons + + + com.devonfw.java.modules + devon4j-rest + + + com.devonfw.java.modules + devon4j-logging + + + com.devonfw.java.modules + devon4j-security + + + + javax.servlet + javax.servlet-api + provided + + + + com.devonfw.java.modules + devon4j-test + test + + + diff --git a/myapp/api/src/main/java/com/example/domain/myapp/general/common/api/ApplicationEntity.java b/myapp/api/src/main/java/com/example/domain/myapp/general/common/api/ApplicationEntity.java new file mode 100644 index 0000000..a660211 --- /dev/null +++ b/myapp/api/src/main/java/com/example/domain/myapp/general/common/api/ApplicationEntity.java @@ -0,0 +1,11 @@ +package com.example.domain.myapp.general.common.api; + +import com.devonfw.module.basic.common.api.entity.GenericEntity; + +/** + * This is the abstract interface for a {@link GenericEntity} of this application. We are using {@link Long} for + * all {@link #getId() primary keys}. + */ +public abstract interface ApplicationEntity extends GenericEntity { + +} diff --git a/myapp/api/src/test/java/com/example/domain/myapp/ToTest.java b/myapp/api/src/test/java/com/example/domain/myapp/ToTest.java new file mode 100644 index 0000000..1cf441a --- /dev/null +++ b/myapp/api/src/test/java/com/example/domain/myapp/ToTest.java @@ -0,0 +1,323 @@ +package com.example.domain.myapp; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.Year; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import org.assertj.core.api.SoftAssertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.util.ReflectionUtils; + +import com.devonfw.module.basic.common.api.reference.IdRef; +import com.devonfw.module.basic.common.api.reflect.Devon4jPackage; +import com.devonfw.module.basic.common.api.to.AbstractTo; +import com.devonfw.module.test.common.base.ModuleTest; + +import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.EqualsVerifierApi; +import nl.jqno.equalsverifier.Warning; + +public class ToTest extends ModuleTest { + + private static final ToExclusions EXCLUSIONS = new ToExclusions(); + + static { + // EXCLUSIONS.add(MyBusinessEto.class).ignoreEquals().ignoreProperties("foo", "bar"); + } + + /** + * Finds all {@link AbstractTo Transportobjekte} of this app via reflection and tests all getters/setters as well as equals and hashCode. + */ + @Test + public void testTos() { + + List> toClasses = getToClasses(); + SoftAssertions assertion = new SoftAssertions(); + for (Class toClass : toClasses) { + ToExclusion exclusion = EXCLUSIONS.get(toClass.getName()); + testGetSet(toClass, assertion, exclusion); + testEqualsAndHashcode(toClass, assertion, exclusion); + } + assertion.assertAll(); + } + + /** + * Checks if a certain class has a custom equals method + * @param clazz class to be checked + * @return boolean value if the class to be checked has a custom equals() + * method or not + */ + private boolean hasCustomEquals(Class clazz) { + + try { + clazz.getDeclaredMethod("equals", new Class[] {}); + } catch (NoSuchMethodException noCustomEquals) { + return false; + } + + return true; + } + + /** + * Checks if a certain class has a custom hashCode method + * + * @param clazz class to be checked + * @return boolean value if the class to be checked has a custom hashCode() + * method or not + */ + private boolean hasCustomHashCode(Class clazz) { + + try { + clazz.getDeclaredMethod("hashCode", new Class[] { Object.class }); + } catch (NoSuchMethodException noCustomHashCode) { + return false; + } + + return true; + } + + private void testEqualsAndHashcode(Class clazz, SoftAssertions assertion, ToExclusion exclusion) { + + if(!hasCustomEquals(clazz) && !hasCustomHashCode(clazz)) { + return; + } + + if ((exclusion != null) && (exclusion.ignoreEquals)) { + return; + } + EqualsVerifierApi verifier = EqualsVerifier.forClass(clazz).withRedefinedSuperclass().usingGetClass().suppress(Warning.NONFINAL_FIELDS, Warning.INHERITED_DIRECTLY_FROM_OBJECT); + try { + verifier.verify(); + } catch (AssertionError e) { + assertion.fail(e.getMessage(), e); + } + } + + private void testGetSet(Class clazz, SoftAssertions assertion, ToExclusion exclusion) { + + if (!Modifier.isAbstract(clazz.getModifiers())) { + ReflectionUtils.doWithLocalFields(clazz, field -> { + try { + if (isCheckable(clazz, field, exclusion)) { + Object testInstance = clazz.newInstance(); + Method getMethod = null; + Method setMethod = null; + + if (Boolean.class.equals(field.getType()) || boolean.class.equals(field.getType())) { + getMethod = findMethod("is", clazz, field); + if (getMethod == null) { + getMethod = findMethod("get", clazz, field); + } + } else { + getMethod = findMethod("get", clazz, field); + } + setMethod = findMethod("set", clazz, field); + + if (getMethod == null) { + assertion.fail("Getter of field " + clazz.getSimpleName() + "." + field.getName() + " has not been found."); + } else if (setMethod == null) { + assertion.fail("Setter of field " + clazz.getSimpleName() + "." + field.getName() + " has not been found."); + } else { + getMethod.setAccessible(true); + setMethod.setAccessible(true); + + Object value = createTestObject(field); + setMethod.invoke(testInstance, value); + Object value2 = getMethod.invoke(testInstance); + assertion.assertThat(value2).as("Value from getter of field " + clazz.getSimpleName() + "." + field.getName()).isEqualTo(value); + } + } + } catch (Exception e) { + assertion.fail("Error with getter/setter of field " + clazz.getSimpleName() + "." + field.getName() + ": " + + e.getClass().getSimpleName() + ": " + e.getMessage(), e); + } + }); + } + } + + private boolean isCheckable(Class clazz, Field field, ToExclusion exclusion) { + + if (field.getName().startsWith("$") || Modifier.isFinal(field.getModifiers())) { + return false; + } + if (Optional.class.isAssignableFrom(field.getType())) { + return false; + } + if (Modifier.isTransient(field.getModifiers())) { + return false; + } + if ((exclusion != null) && (exclusion.properties.contains(field.getName()))) { + return false; + } + return true; + } + + private Object createTestObject(Field field) throws InstantiationException, IllegalAccessException { + + Class type = field.getType(); + return createInstance(type); + } + + private Object createInstance(Class type) throws InstantiationException, IllegalAccessException { + + Object o = null; + if (type.isEnum()) { + o = type.getEnumConstants()[0]; + } else if (List.class.isAssignableFrom(type)) { + o = new ArrayList<>(); + } else if (Set.class.isAssignableFrom(type)) { + o = new HashSet<>(); + } else if (Map.class.isAssignableFrom(type)) { + o = new HashMap<>(); + } else if (Integer.class.isAssignableFrom(type) || int.class.isAssignableFrom(type)) { + o = Integer.valueOf(1); + } else if (Long.class.isAssignableFrom(type) || long.class.isAssignableFrom(type)) { + o = Long.valueOf(2); + } else if (Boolean.class.isAssignableFrom(type) || boolean.class.isAssignableFrom(type)) { + o = Boolean.TRUE; + } else if (String.class.isAssignableFrom(type)) { + o = "hello world"; + } else if (Year.class.isAssignableFrom(type)) { + o = Year.of(1999); + } else if (Instant.class.isAssignableFrom(type)) { + o = Instant.now(); + } else if (Timestamp.class.isAssignableFrom(type)) { + o = Timestamp.from(Instant.now()); + } else if (type == byte[].class) { + o = "test".getBytes(); + } else if (Serializable.class.equals(type)) { + o = Integer.valueOf(1); + } else if (type == BigDecimal.class) { + o = BigDecimal.ZERO; + } else if (type == BigInteger.class) { + o = BigInteger.ZERO; + } else if (type == Integer.class) { + o = Integer.valueOf(0); + } else if ((type == Long.class) || (type == Number.class)) { + o = Long.valueOf(0); + } else if (type == Double.class) { + o = Double.valueOf(0); + } else if (type == IdRef.class) { + o = IdRef.of(0); + } + return o; + } + + private static Method findMethod(String prefix, Class clazz, Field field) { + + String methodname = prefix + field.getName(); + + return Arrays.asList(ReflectionUtils.getAllDeclaredMethods(clazz)).stream() + .filter(m -> m.getName().equalsIgnoreCase(methodname)).findFirst().orElse(null); + } + + private List> getToClasses() { + + ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); + provider.addIncludeFilter(new AssignableTypeFilter(AbstractTo.class)); + + Devon4jPackage pkg = Devon4jPackage.of(ToTest.class); + Set toSet = provider.findCandidateComponents(pkg.getRoot()); + List> toList = new ArrayList<>(toSet.size()); + for (BeanDefinition beanDefinition : toSet) { + String className = beanDefinition.getBeanClassName(); + try { + Class toClass = Class.forName(className); + toList.add(toClass); + } catch (ClassNotFoundException e) { + fail("Class " + className + " could not been found."); + } + } + return toList; + } + + public static class ToExclusions { + + private final Map exclusions; + + public ToExclusions() { + + super(); + this.exclusions = new HashMap<>(); + } + + public ToExclusion add(Class toClass) { + + return add(toClass.getName()); + } + + public ToExclusion add(String toClassQualifiedName) { + + ToExclusion exclusion = new ToExclusion(); + ToExclusion duplicate = this.exclusions.put(toClassQualifiedName, exclusion); + if (duplicate != null) { + throw new IllegalStateException("Doppelte ToExclusion von " + toClassQualifiedName); + } + return exclusion; + } + + public ToExclusion get(String toClassQualifiedName) { + + return this.exclusions.get(toClassQualifiedName); + } + + } + + public static class ToExclusion { + + private Set properties; + + private boolean ignoreEquals; + + public ToExclusion() { + + super(); + this.properties = new HashSet<>(); + this.ignoreEquals = false; + } + + /** + * Ignores the given properties for testing of getters/setters. + * + * @return this + */ + public ToExclusion ignoreProperties(String... props) { + + if (this.properties == null) { + this.properties = new HashSet<>(); + } + for (String property : props) { + this.properties.add(property); + } + return this; + } + + /** + * Ignores this transfer-object for testing of equals and hashCode with {@link EqualsVerifier}. + * + * @return this + */ + public ToExclusion ignoreEquals() { + + this.ignoreEquals = true; + return this; + } + } +} \ No newline at end of file diff --git a/myapp/core/pom.xml b/myapp/core/pom.xml new file mode 100644 index 0000000..d933be8 --- /dev/null +++ b/myapp/core/pom.xml @@ -0,0 +1,233 @@ + + + 4.0.0 + + com.example.domain + myapp + ${revision} + + myapp-core + jar + ${project.artifactId} + Core of the server for the myapp application - a simple example based on devon4j. + + + + ${project.groupId} + myapp-api + ${project.version} + + + + + com.devonfw.java.modules + devon4j-beanmapping-orika + + + + + com.devonfw.java.starters + devon4j-starter-security + + + + com.devonfw.java.modules + devon4j-web + + + + + + + + + + + + com.devonfw.java.starters + devon4j-starter-cxf-server-rest + + + + + + + com.devonfw.java.starters + devon4j-starter-spring-data-jpa + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + + javax.persistence + javax.persistence-api + + + + + org.hibernate + hibernate-entitymanager + + + + + com.querydsl + querydsl-jpa + + + com.querydsl + querydsl-apt + provided + + + + + org.hibernate.validator + hibernate-validator + + + + + javax.servlet + javax.servlet-api + provided + + + + + javax.el + javax.el-api + + + + + org.springframework + spring-webmvc + + + + + com.h2database + h2 + + + + + org.flywaydb + flyway-core + + + + + org.apache.cxf + cxf-rt-rs-service-description + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.springframework + spring-aop + + + + + cglib + cglib + + + + + net.logstash.logback + logstash-logback-encoder + + + + + com.devonfw.java.modules + devon4j-test-jpa + test + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-validation + + + + + + + + embedded + + true + + + + org.springframework.boot + spring-boot-starter-tomcat + + ${spring.boot.version} + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + config/application.properties + + + + + + + diff --git a/myapp/core/src/main/java/com/example/domain/myapp/SpringBootApp.java b/myapp/core/src/main/java/com/example/domain/myapp/SpringBootApp.java new file mode 100644 index 0000000..05728ab --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/SpringBootApp.java @@ -0,0 +1,29 @@ +package com.example.domain.myapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; + +import com.devonfw.module.jpa.dataaccess.api.AdvancedRevisionEntity; +import com.devonfw.module.jpa.dataaccess.impl.data.GenericRepositoryFactoryBean; + +/** + * Main entry point of this {@link SpringBootApplication}. Simply run this class to start this app. + */ +@SpringBootApplication +@EnableJpaRepositories(repositoryFactoryBeanClass = GenericRepositoryFactoryBean.class) +@EnableGlobalMethodSecurity(jsr250Enabled = true) +public class SpringBootApp { + + /** + * Entry point for spring-boot based app + * + * @param args - arguments + */ + public static void main(String[] args) { + + SpringApplication.run(SpringBootApp.class, args); + } +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/common/api/security/ApplicationAccessControlConfig.java b/myapp/core/src/main/java/com/example/domain/myapp/general/common/api/security/ApplicationAccessControlConfig.java new file mode 100644 index 0000000..0389789 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/common/api/security/ApplicationAccessControlConfig.java @@ -0,0 +1,32 @@ +package com.example.domain.myapp.general.common.api.security; + +import javax.inject.Named; + +import com.devonfw.module.security.common.api.accesscontrol.AccessControlGroup; +import com.devonfw.module.security.common.base.accesscontrol.AccessControlConfig; + +/** + * Example of {@link AccessControlConfig} that used for testing. + */ +@Named +public class ApplicationAccessControlConfig extends AccessControlConfig { + + public static final String APP_ID = "myapp"; + + private static final String PREFIX = APP_ID + "."; + + public static final String GROUP_READ_MASTER_DATA = PREFIX + "ReadMasterData"; + + public static final String GROUP_ADMIN = "Admin"; + + /** + * The constructor. + */ + public ApplicationAccessControlConfig() { + + super(); + AccessControlGroup readMasterData = group(GROUP_READ_MASTER_DATA); + group(GROUP_ADMIN, readMasterData); + } + +} \ No newline at end of file diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/common/base/AbstractBeanMapperSupport.java b/myapp/core/src/main/java/com/example/domain/myapp/general/common/base/AbstractBeanMapperSupport.java new file mode 100644 index 0000000..b66cb57 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/common/base/AbstractBeanMapperSupport.java @@ -0,0 +1,31 @@ +package com.example.domain.myapp.general.common.base; + +import com.devonfw.module.beanmapping.common.api.BeanMapper; + +import javax.inject.Inject; + +/** + * This abstract class provides {@link #getBeanMapper() access} to the {@link BeanMapper}. + */ +public abstract class AbstractBeanMapperSupport { + + private BeanMapper beanMapper; + + /** + * @param beanMapper is the {@link BeanMapper} to {@link Inject} + */ + @Inject + public void setBeanMapper(BeanMapper beanMapper) { + + this.beanMapper = beanMapper; + } + + /** + * @return the {@link BeanMapper} instance. + */ + protected BeanMapper getBeanMapper() { + + return this.beanMapper; + } + +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/config/ApplicationObjectMapperFactory.java b/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/config/ApplicationObjectMapperFactory.java new file mode 100644 index 0000000..dc8f862 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/config/ApplicationObjectMapperFactory.java @@ -0,0 +1,47 @@ +package com.example.domain.myapp.general.common.impl.config; + +import javax.inject.Named; + +import org.springframework.security.web.csrf.CsrfToken; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.devonfw.module.json.common.base.ObjectMapperFactory; + + +/** + * The MappingFactory class to resolve polymorphic conflicts within the myapp application. + */ +@Named("ApplicationObjectMapperFactory") +public class ApplicationObjectMapperFactory extends ObjectMapperFactory { + + /** + * The constructor. + */ + public ApplicationObjectMapperFactory() { + super(); + } + + /** + * override createInstance method. + */ + @Override + public ObjectMapper createInstance() { + + ObjectMapper objectMapper = super.createInstance(); + // omit properties in JSON that are null + objectMapper.setSerializationInclusion(Include.NON_NULL); + // Write legacy date/calendar as readable text instead of numeric value + // See + // https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/SerializationFeature.html#WRITE_DATES_AS_TIMESTAMPS + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + // ignore unknown properties in JSON to prevent errors + // e.g. when the service has been updated/extended but the calling REST client is not yet updated + // see https://github.com/devonfw/devon4j/blob/develop/documentation/guide-service-layer.asciidoc#versioning + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return objectMapper; + } +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/config/BeansOrikaConfig.java b/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/config/BeansOrikaConfig.java new file mode 100644 index 0000000..81a0d7b --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/config/BeansOrikaConfig.java @@ -0,0 +1,14 @@ +package com.example.domain.myapp.general.common.impl.config; + +import org.springframework.context.annotation.Configuration; + +import com.devonfw.module.beanmapping.common.base.BaseOrikaConfig; + +/** + * Java bean configuration for Orika. The method {@link #configureCustomMapping(MapperFactory)} from + * {@link BaseOrikaConfig} can be overridden as per requirements. + */ +@Configuration +public class BeansOrikaConfig extends BaseOrikaConfig { + +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/security/BaseUserDetailsService.java b/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/security/BaseUserDetailsService.java new file mode 100644 index 0000000..1b7dbcf --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/security/BaseUserDetailsService.java @@ -0,0 +1,111 @@ +package com.example.domain.myapp.general.common.impl.security; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import com.devonfw.module.security.common.api.accesscontrol.AccessControl; +import com.devonfw.module.security.common.api.accesscontrol.AccessControlProvider; +import com.devonfw.module.security.common.base.accesscontrol.AccessControlGrantedAuthority; + +/** + * Custom implementation of {@link UserDetailsService}.
+ * + * @see com.example.domain.myapp.general.service.impl.config.BaseWebSecurityConfig + */ +@Named +public class BaseUserDetailsService implements UserDetailsService { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(BaseUserDetailsService.class); + + private AuthenticationManagerBuilder amBuilder; + + private AccessControlProvider accessControlProvider; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + + try { + UserDetails user = getAmBuilder().getDefaultUserDetailsService().loadUserByUsername(username); + return new User(user.getUsername(), user.getPassword(), getAuthorities(user)); + } catch (Exception e) { + throw new UsernameNotFoundException("Authentication failed, for user:" + username, e); + } + } + + /** + * @param user the {@link UserDetails} from spring-security. + * @return the associated {@link GrantedAuthority}s + * @throws AuthenticationException if no principal is retrievable for the given {@code username} + */ + protected Set getAuthorities(UserDetails user) throws AuthenticationException { + + // determine granted authorities for spring-security... + Set accessControlSet = new HashSet<>(); + + Set undefinedIds = getRoles(user).stream() + .filter(id -> !this.accessControlProvider.collectAccessControls(id, accessControlSet)) + .collect(Collectors.toUnmodifiableSet()); + + undefinedIds.forEach(id -> LOG.warn("Undefined access control {}.", id)); + + return accessControlSet.stream().map(accessControl -> new AccessControlGrantedAuthority(accessControl)) + .collect(Collectors.toUnmodifiableSet()); + } + + private Collection getRoles(UserDetails user) { + return user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toUnmodifiableSet()); + } + + /** + * @return amBuilder + */ + public AuthenticationManagerBuilder getAmBuilder() { + + return this.amBuilder; + } + + /** + * @param amBuilder new value of {@link #getAmBuilder}. + */ + @Inject + public void setAmBuilder(AuthenticationManagerBuilder amBuilder) { + + this.amBuilder = amBuilder; + } + + /** + * @return accessControlProvider + */ + public AccessControlProvider getAccessControlProvider() { + + return this.accessControlProvider; + } + + /** + * @param accessControlProvider new value of {@link #getAccessControlProvider}. + */ + @Inject + public void setAccessControlProvider(AccessControlProvider accessControlProvider) { + + this.accessControlProvider = accessControlProvider; + } +} + diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/security/CsrfRequestMatcher.java b/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/security/CsrfRequestMatcher.java new file mode 100644 index 0000000..a9db0a2 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/common/impl/security/CsrfRequestMatcher.java @@ -0,0 +1,56 @@ +package com.example.domain.myapp.general.common.impl.security; + +import java.util.regex.Pattern; + +import javax.inject.Named; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.security.web.util.matcher.RequestMatcher; + +/** + * This is the implementation of {@link RequestMatcher}, which decides which {@link HttpServletRequest Requests} require + * a correct CSRF token. + * + * @see Cross-site request forgery + */ +@Named("CsrfRequestMatcher") +public class CsrfRequestMatcher implements RequestMatcher { + + private static final Pattern HTTP_METHOD_PATTERN = Pattern.compile("^GET$"); + + private static final String[] PATH_PREFIXES_WITHOUT_CSRF_PROTECTION = + { "/login", "/logout", "/services/rest/login", "/websocket" }; + + @Override + public boolean matches(HttpServletRequest request) { + + // GET requests are read-only and therefore do not need CSRF protection + if (HTTP_METHOD_PATTERN.matcher(request.getMethod()).matches()) { + + return false; + } + + // There are specific URLs which can not be protected from CSRF. For example, in case of the the login page, + // the CSRF token can only be accessed after a successful authentication ("login"). + String requestPath = getRequestPath(request); + for (String path : PATH_PREFIXES_WITHOUT_CSRF_PROTECTION) { + if (requestPath.startsWith(path)) { + return false; + } + } + + return true; + } + + private String getRequestPath(HttpServletRequest request) { + + String url = request.getServletPath(); + String pathInfo = request.getPathInfo(); + + if (pathInfo != null) { + url += pathInfo; + } + + return url; + } +} \ No newline at end of file diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/dataaccess/api/ApplicationPersistenceEntity.java b/myapp/core/src/main/java/com/example/domain/myapp/general/dataaccess/api/ApplicationPersistenceEntity.java new file mode 100644 index 0000000..f4cc73d --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/dataaccess/api/ApplicationPersistenceEntity.java @@ -0,0 +1,86 @@ +package com.example.domain.myapp.general.dataaccess.api; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Transient; +import javax.persistence.Version; + +import com.example.domain.myapp.general.common.api.ApplicationEntity; +import com.devonfw.module.basic.common.api.entity.PersistenceEntity; + +/** + * Abstract base class for all {@link PersistenceEntity persistence entities} with an {@link #getId() id} and a + * {@link #getModificationCounter() modificationCounter} (version) field. All persistence entities of this application + * should inherit from this class. It is using JPA annotations at the getters what has several advantages but also + * implies that you have to annotate transient getter methods with the {@link Transient} annotation. + */ +@MappedSuperclass +public abstract class ApplicationPersistenceEntity implements ApplicationEntity, PersistenceEntity { + + private static final long serialVersionUID = 1L; + + private Long id; + + private int modificationCounter; + + /** + * The constructor. + */ + public ApplicationPersistenceEntity() { + + super(); + } + + @Override + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getId() { + + return this.id; + } + + @Override + public void setId(Long id) { + + this.id = id; + } + + @Override + @Version + public int getModificationCounter() { + + return this.modificationCounter; + } + + @Override + public void setModificationCounter(int modificationCounter) { + + this.modificationCounter = modificationCounter; + } + + @Override + public String toString() { + + StringBuilder buffer = new StringBuilder(); + toString(buffer); + return buffer.toString(); + } + + /** + * Method to extend {@link #toString()} logic. + * + * @param buffer is the {@link StringBuilder} where to {@link StringBuilder#append(Object) append} the string + * representation. + */ + protected void toString(StringBuilder buffer) { + + buffer.append(getClass().getSimpleName()); + if (this.id != null) { + buffer.append("[id="); + buffer.append(this.id); + buffer.append("]"); + } + } +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/dataaccess/impl/JpaConfig.java b/myapp/core/src/main/java/com/example/domain/myapp/general/dataaccess/impl/JpaConfig.java new file mode 100644 index 0000000..485bb87 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/dataaccess/impl/JpaConfig.java @@ -0,0 +1,27 @@ +package com.example.domain.myapp.general.dataaccess.impl; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +import com.devonfw.module.basic.common.api.config.SpringProfileConstants; +import com.devonfw.module.jpa.dataaccess.api.JpaInitializer; + +/** + * Spring {@link Configuration} for JPA. + */ +@Configuration +@Profile(SpringProfileConstants.NOT_JUNIT) +public class JpaConfig { + + /** + * @return the {@link JpaInitializer} to register the {@link javax.persistence.EntityManager} and make + * {@link com.devonfw.module.jpa.dataaccess.api.JpaHelper} functional. + */ + @Bean + public JpaInitializer jpaInitializer() { + + return new JpaInitializer(); + } + +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractComponentFacade.java b/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractComponentFacade.java new file mode 100644 index 0000000..5cf8db0 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractComponentFacade.java @@ -0,0 +1,16 @@ +package com.example.domain.myapp.general.logic.base; + +/** + * Abstract base class for any component implementation class in this application. + */ +public abstract class AbstractComponentFacade extends AbstractLogic { + + /** + * The constructor. + */ + public AbstractComponentFacade() { + + super(); + } + +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractLogic.java b/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractLogic.java new file mode 100644 index 0000000..c80be9d --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractLogic.java @@ -0,0 +1,107 @@ +package com.example.domain.myapp.general.logic.base; + +import com.example.domain.myapp.general.common.base.AbstractBeanMapperSupport; + +import com.devonfw.module.basic.common.api.entity.GenericEntity; +import com.devonfw.module.basic.common.api.to.AbstractEto; +import com.devonfw.module.basic.common.api.to.MasterCto; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Abstract base class for implementations of business logic in this application. Actual implementations need + * to be annotated with {@link javax.inject.Named}. + * + * @see AbstractUc + * @see AbstractComponentFacade + */ +public abstract class AbstractLogic extends AbstractBeanMapperSupport { + + /** + * The constructor. + */ + public AbstractLogic() { + + super(); + } + + /** + * Creates a {@link Map} with all {@link MasterCto}s from the given {@link Collection} using their + * {@link MasterCto#getEto() main ETO} {@link AbstractEto#getId() ID} as key. All {@link AbstractEto ETO}s being + * {@code null} or without an {@link AbstractEto#getId() ID} will be ignored. + * + * @param is the generic type of the {@link MasterCto}s. + * @param entities is the {@link Collection} of {@link MasterCto}s. + * @return a {@link Map} mapping from {@link AbstractEto#getId() ID} to {@link MasterCto}. + */ + protected static > Map getCtoMap(Collection ctos) { + + Map id2CtoMap = new HashMap<>(); + for (C cto : ctos) { + AbstractEto eto = cto.getEto(); + if (eto != null) { + Long id = eto.getId(); + if (id != null) { + id2CtoMap.put(id, cto); + } + } + } + return id2CtoMap; + } + + /** + * Creates a {@link Map} with all {@link GenericEntity entities} from the given {@link Collection} using their + * {@link GenericEntity#getId() ID} as key. All {@link GenericEntity entities} without an + * {@link GenericEntity#getId() ID} ({@code null}) will be ignored. + * + * @param is the generic type of the {@link GenericEntity#getId() ID}. + * @param is the generic type of the {@link GenericEntity entity}. + * @param entities is the {@link Collection} of {@link GenericEntity entities}. + * @return a {@link Map} mapping from {@link GenericEntity#getId() ID} to {@link GenericEntity entity}. + */ + protected static > Map getEntityMap(Collection entities) { + + Map id2EntityMap = new HashMap<>(); + for (E entity : entities) { + ID id = entity.getId(); + if (id != null) { + id2EntityMap.put(id, entity); + } + } + return id2EntityMap; + } + + /** + * Determines the {@link GenericEntity entities} to delete if currentList is the current list from the + * persistence and listToSave is the new list that shall be saved. In other words this method selects the + * {@link GenericEntity entities} from currentList that are not contained in listToSave. + * + * @param is the generic type of the {@link GenericEntity#getId() ID}. + * @param is the generic type of the {@link GenericEntity entity}. + * @param currentEntities is the {@link Collection} of the {@link GenericEntity entities} currently persisted. We + * assume that all objects in this list have an {@link GenericEntity#getId() ID} value (that is not + * {@code null}). + * @param entitiesToSave is the {@link Collection} that contains the {@link GenericEntity entities} that shall be + * saved. It may contain {@link GenericEntity entities} that have no {@link GenericEntity#getId() ID} that + * shall be newly created. + * @return the {@link List} with the {@link GenericEntity entities} to delete. + */ + protected static > List getEntities2Delete(Collection currentEntities, + Collection entitiesToSave) { + + List result = new ArrayList<>(currentEntities.size()); + Map entityMap = getEntityMap(entitiesToSave); + for (E entity : currentEntities) { + if (!entityMap.containsKey(entity.getId())) { + // entity from currentList is not contained in listToSave... + result.add(entity); + } + } + return result; + } + +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractUc.java b/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractUc.java new file mode 100644 index 0000000..402c544 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/logic/base/AbstractUc.java @@ -0,0 +1,18 @@ +package com.example.domain.myapp.general.logic.base; + +/** + * Abstract base class for any use case in this application. Actual implementations need to be annotated with + * {@link javax.inject.Named}. + * + */ +public abstract class AbstractUc extends AbstractLogic { + + /** + * The constructor. + */ + public AbstractUc() { + + super(); + } + +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/BaseWebSecurityConfig.java b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/BaseWebSecurityConfig.java new file mode 100644 index 0000000..21a7094 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/BaseWebSecurityConfig.java @@ -0,0 +1,117 @@ +package com.example.domain.myapp.general.service.impl.config; + +import javax.inject.Inject; +import javax.servlet.Filter; + +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import com.devonfw.module.security.common.api.config.WebSecurityConfigurer; +import com.devonfw.module.security.common.impl.rest.AuthenticationSuccessHandlerSendingOkHttpStatusCode; +import com.devonfw.module.security.common.impl.rest.JsonUsernamePasswordAuthenticationFilter; +import com.devonfw.module.security.common.impl.rest.LogoutSuccessHandlerReturningOkHttpStatusCode; + +/** + * This type serves as a base class for extensions of the {@code WebSecurityConfigurerAdapter} and provides a default + * configuration.
+ * Security configuration is based on {@link WebSecurityConfigurerAdapter}. This configuration is by purpose designed + * most simple for two channels of authentication: simple login form and rest-url. + */ +public abstract class BaseWebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Inject + private UserDetailsService userDetailsService; + + @Inject + private PasswordEncoder passwordEncoder; + + @Inject + private WebSecurityConfigurer webSecurityConfigurer; + + + + /** + * Configure spring security to enable a simple webform-login + a simple rest login. + */ + @Override + public void configure(HttpSecurity http) throws Exception { + + String[] unsecuredResources = new String[] { "/login", "/security/**", "/services/rest/login", + "/services/rest/logout" }; + + // disable CSRF protection by default, use csrf starter to override. + http = http.csrf().disable(); + // load starters as pluggins. + http = this.webSecurityConfigurer.configure(http); + + http + // + .userDetailsService(this.userDetailsService) + // define all urls that are not to be secured + .authorizeRequests().antMatchers(unsecuredResources).permitAll().anyRequest().authenticated().and() + // configure parameters for simple form login (and logout) + .formLogin().successHandler(new SimpleUrlAuthenticationSuccessHandler()).defaultSuccessUrl("/") + .failureUrl("/login.html?error").loginProcessingUrl("/j_spring_security_login").usernameParameter("username") + .passwordParameter("password").and() + // logout via POST is possible + .logout().logoutSuccessUrl("/login.html").and() + // register login and logout filter that handles rest logins + .addFilterAfter(getSimpleRestAuthenticationFilter(), BasicAuthenticationFilter.class) + .addFilterAfter(getSimpleRestLogoutFilter(), LogoutFilter.class); + } + + /** + * Create a simple filter that allows logout on a REST Url /services/rest/logout and returns a simple HTTP status 200 + * ok. + * + * @return the filter. + */ + protected Filter getSimpleRestLogoutFilter() { + + LogoutFilter logoutFilter = new LogoutFilter(new LogoutSuccessHandlerReturningOkHttpStatusCode(), + new SecurityContextLogoutHandler()); + + // configure logout for rest logouts + logoutFilter.setLogoutRequestMatcher(new AntPathRequestMatcher("/services/rest/logout")); + + return logoutFilter; + } + + /** + * Create a simple authentication filter for REST logins that reads user-credentials from a json-parameter and returns + * status 200 instead of redirect after login. + * + * @return the {@link JsonUsernamePasswordAuthenticationFilter}. + * @throws Exception if something goes wrong. + */ + protected JsonUsernamePasswordAuthenticationFilter getSimpleRestAuthenticationFilter() throws Exception { + + JsonUsernamePasswordAuthenticationFilter jsonFilter = new JsonUsernamePasswordAuthenticationFilter( + new AntPathRequestMatcher("/services/rest/login")); + jsonFilter.setPasswordParameter("j_password"); + jsonFilter.setUsernameParameter("j_username"); + jsonFilter.setAuthenticationManager(authenticationManager()); + // set failurehandler that uses no redirect in case of login failure; just HTTP-status: 401 + jsonFilter.setAuthenticationManager(authenticationManagerBean()); + jsonFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler()); + // set successhandler that uses no redirect in case of login success; just HTTP-status: 200 + jsonFilter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandlerSendingOkHttpStatusCode()); + return jsonFilter; + } + + @SuppressWarnings("javadoc") + @Inject + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("admin").password(this.passwordEncoder.encode("admin")).authorities("Admin"); + } + +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/ServletInitializer.java b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/ServletInitializer.java new file mode 100644 index 0000000..93f557f --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/ServletInitializer.java @@ -0,0 +1,23 @@ +package com.example.domain.myapp.general.service.impl.config; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Configuration; + +import com.example.domain.myapp.SpringBootApp; + +/** + * This auto configuration will be used by spring boot to enable traditional deployment to a servlet container. You may + * remove this class if you run your application with embedded tomcat only. Tomcat startup will be twice as fast. + */ +@Configuration +@EnableAutoConfiguration +public class ServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + + return application.sources(SpringBootApp.class); + } +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebConfig.java b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebConfig.java new file mode 100644 index 0000000..031232a --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebConfig.java @@ -0,0 +1,90 @@ +package com.example.domain.myapp.general.service.impl.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.CharacterEncodingFilter; + +import com.devonfw.module.logging.common.api.DiagnosticContextFacade; +import com.devonfw.module.logging.common.impl.DiagnosticContextFacadeImpl; +import com.devonfw.module.logging.common.impl.DiagnosticContextFilter; +import com.devonfw.module.logging.common.impl.PerformanceLogFilter; +import com.devonfw.module.service.common.api.constants.ServiceConstants; +import org.springframework.security.config.core.GrantedAuthorityDefaults; + +/** + * Registers a number of filters for web requests. + */ +@Configuration +public class WebConfig { + + private @Autowired AutowireCapableBeanFactory beanFactory; + + /** + * @return the {@link FilterRegistrationBean} to register the {@link PerformanceLogFilter} that will log all requests + * with their duration and status code. + */ + @Bean + public FilterRegistrationBean performanceLogFilter() { + + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + PerformanceLogFilter performanceLogFilter = new PerformanceLogFilter(); + this.beanFactory.autowireBean(performanceLogFilter); + registration.setFilter(performanceLogFilter); + registration.addUrlPatterns("/*"); + return registration; + } + + /** + * @return the {@link DiagnosticContextFacade} implementation. + */ + @Bean(name = "DiagnosticContextFacade") + public DiagnosticContextFacade diagnosticContextFacade() { + + return new DiagnosticContextFacadeImpl(); + } + + /** + * @return the {@link FilterRegistrationBean} to register the {@link DiagnosticContextFilter} that adds the + * correlation id as MDC so it will be included in all associated logs. + */ + @Bean + public FilterRegistrationBean diagnosticContextFilter() { + + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + DiagnosticContextFilter diagnosticContextFilter = new DiagnosticContextFilter(); + this.beanFactory.autowireBean(diagnosticContextFilter); + registration.setFilter(diagnosticContextFilter); + registration.addUrlPatterns(ServiceConstants.URL_PATH_SERVICES + "/*"); + return registration; + } + + /** + * @return the {@link FilterRegistrationBean} to register the {@link CharacterEncodingFilter} to set the encoding. + */ + @Bean + public FilterRegistrationBean setCharacterEncodingFilter() { + + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); + characterEncodingFilter.setEncoding("UTF-8"); + characterEncodingFilter.setForceEncoding(false); + this.beanFactory.autowireBean(characterEncodingFilter); + registration.setFilter(characterEncodingFilter); + registration.addUrlPatterns("/*"); + return registration; + } + + /** + * @return the {@link GrantedAuthorityDefaults} to configure the "role prefix" to the empty string. By default + * spring-security is magically adding a strange prefix called "ROLE_" to your granted authorities. In order + * to prevent this we use this class with an empty prefix. + */ + @Bean + public GrantedAuthorityDefaults grantedAuthorityDefaults() { + + return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix + } +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebSecurityBeansConfig.java b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebSecurityBeansConfig.java new file mode 100644 index 0000000..f046171 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebSecurityBeansConfig.java @@ -0,0 +1,37 @@ +package com.example.domain.myapp.general.service.impl.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.csrf.CsrfTokenRepository; +import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; + +/** + * This configuration class provides factory methods for several Spring security related beans. + */ +@Configuration +public class WebSecurityBeansConfig { + + /** + * This method provides a new instance of {@code CsrfTokenRepository} + * + * @return the newly created {@code CsrfTokenRepository} + */ + @Bean + public CsrfTokenRepository csrfTokenRepository() { + + return new HttpSessionCsrfTokenRepository(); + } + + /** + * This method provide a new instance of {@code DelegatingPasswordEncoder} + * + * @return the newly create {@code DelegatingPasswordEncoder} + */ + @Bean + public PasswordEncoder passwordEncoder() { + + return PasswordEncoderFactories.createDelegatingPasswordEncoder(); + } +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebSecurityConfig.java b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebSecurityConfig.java new file mode 100644 index 0000000..b34cfa0 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/config/WebSecurityConfig.java @@ -0,0 +1,21 @@ +package com.example.domain.myapp.general.service.impl.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +import com.devonfw.module.basic.common.api.config.SpringProfileConstants; + +/** + * Security configuration based on {@link WebSecurityConfigurerAdapter}. This configuration is by purpose designed most + * simple for two channels of authentication: simple login form and rest-url. (Copied from + * {@link com.example.domain.myapp.general.service.impl.config.BaseWebSecurityConfig} + * + */ +@Configuration +@EnableWebSecurity +@Profile(SpringProfileConstants.NOT_JUNIT) +public class WebSecurityConfig extends BaseWebSecurityConfig { + +} diff --git a/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/rest/ApplicationAccessDeniedHandler.java b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/rest/ApplicationAccessDeniedHandler.java new file mode 100644 index 0000000..9e97ae0 --- /dev/null +++ b/myapp/core/src/main/java/com/example/domain/myapp/general/service/impl/rest/ApplicationAccessDeniedHandler.java @@ -0,0 +1,46 @@ +package com.example.domain.myapp.general.service.impl.rest; + +import com.devonfw.module.rest.service.impl.RestServiceExceptionFacade; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.Response; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; + +/** + * Implementation of {@link AccessDeniedHandler}. + */ +@Named("ApplicationAccessDeniedHandler") +public class ApplicationAccessDeniedHandler implements AccessDeniedHandler { + + private RestServiceExceptionFacade exceptionFacade; + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, + AccessDeniedException accessDeniedException) throws IOException, ServletException { + + Response restResponse = this.exceptionFacade.toResponse(accessDeniedException); + Object entity = restResponse.getEntity(); + response.setStatus(restResponse.getStatus()); + if (entity != null) { + response.getWriter().write(entity.toString()); + } + } + + /** + * @param exceptionFacade the {@link RestServiceExceptionFacade} to inject. + */ + @Inject + public void setExceptionFacade(RestServiceExceptionFacade exceptionFacade) { + + this.exceptionFacade = exceptionFacade; + } + +} diff --git a/myapp/core/src/main/resources/META-INF/cxf/org.apache.cxf.Logger b/myapp/core/src/main/resources/META-INF/cxf/org.apache.cxf.Logger new file mode 100644 index 0000000..27dd788 --- /dev/null +++ b/myapp/core/src/main/resources/META-INF/cxf/org.apache.cxf.Logger @@ -0,0 +1 @@ +org.apache.cxf.common.logging.Slf4jLogger \ No newline at end of file diff --git a/myapp/core/src/main/resources/application.properties b/myapp/core/src/main/resources/application.properties new file mode 100644 index 0000000..0b7a39d --- /dev/null +++ b/myapp/core/src/main/resources/application.properties @@ -0,0 +1,36 @@ +# This is the configuration file shipped with the application that contains reasonable defaults. +# Environment specific configurations are configured in config/application.properties. +# If you are running in a servlet container you may add this to lib/config/application.properties in case you do not +# want to touch the WAR file. + +# server.port=8080 + +spring.application.name=myapp +server.servlet.context-path=/ + +security.expose.error.details=false + +spring.jpa.hibernate.ddl-auto=validate + +# Datasource for accessing the database +# https://github.com/spring-projects/spring-boot/blob/d3c34ee3d1bfd3db4a98678c524e145ef9bca51c/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java +spring.jpa.database=h2 +# spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +# spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa + +# Hibernate NamingStrategy has been deprecated and then removed in favor of two step naming strategy ImplicitNamingStrategy and PhysicalNamingStrategy +spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl +spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl + +# https://github.com/devonfw/devon4j/issues/65 +# https://vladmihalcea.com/the-open-session-in-view-anti-pattern/ +spring.jpa.open-in-view=false + +# to prevent that Spring Boot launches batch jobs on startup +# might otherwise lead to errors if job parameters are needed (or lead to unwanted modifications and longer startup times) +# see http://stackoverflow.com/questions/22318907/how-to-stop-spring-batch-scheduled-jobs-from-running-at-first-time-when-executin +spring.batch.job.enabled=false + +# Flyway for Database Setup and Migrations +spring.flyway.locations=classpath:db/migration diff --git a/myapp/core/src/main/resources/config/application.properties b/myapp/core/src/main/resources/config/application.properties new file mode 100644 index 0000000..b48c367 --- /dev/null +++ b/myapp/core/src/main/resources/config/application.properties @@ -0,0 +1,27 @@ +# This is the spring boot configuration file for development. It will not be included into the application. +# In order to set specific configurations in a regular installed environment create an according file +# config/application.properties in the server. If you are deploying the application to a servlet container as untouched +# WAR file you can locate this config folder in ${symbol_dollar}{CATALINA_BASE}/lib. If you want to deploy multiple applications to +# the same container (not recommended by default) you need to ensure the WARs are extracted in webapps folder and locate +# the config folder inside the WEB-INF/classes folder of the webapplication. + +server.port=8081 +server.servlet.context-path=/ + +# Datasource for accessing the database +# See https://github.com/devonfw/devon4j/blob/develop/documentation/guide-configuration.asciidoc#security-configuration +#jasypt.encryptor.password=none +#spring.datasource.password=ENC(7CnHiadYc0Wh2FnWADNjJg==) +spring.datasource.password= +spring.datasource.url=jdbc:h2:./.myapp; + +# print SQL to console for debugging (e.g. detect N+1 issues) +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true + +# Enable JSON pretty printing +spring.jackson.serialization.INDENT_OUTPUT=true + +# Flyway for Database Setup and Migrations +spring.flyway.enabled=true +spring.flyway.clean-on-validation-error=true diff --git a/myapp/core/src/main/resources/db/migration/1.0/V0001__Create_Sequence.sql b/myapp/core/src/main/resources/db/migration/1.0/V0001__Create_Sequence.sql new file mode 100644 index 0000000..6bf006b --- /dev/null +++ b/myapp/core/src/main/resources/db/migration/1.0/V0001__Create_Sequence.sql @@ -0,0 +1,3 @@ +-- Leave a large ID space reserved for master-data and test-data +CREATE SEQUENCE HIBERNATE_SEQUENCE START WITH 1000000; + diff --git a/myapp/core/src/main/resources/db/migration/1.0/V0002__Create_Tables.sql b/myapp/core/src/main/resources/db/migration/1.0/V0002__Create_Tables.sql new file mode 100644 index 0000000..51206ea --- /dev/null +++ b/myapp/core/src/main/resources/db/migration/1.0/V0002__Create_Tables.sql @@ -0,0 +1,8 @@ +CREATE TABLE EMPLOYEE ( + id BIGINT auto_increment, + modificationCounter INTEGER NOT NULL, + employeeid BIGINT auto_increment, + name VARCHAR(255), + surname VARCHAR(255), + email VARCHAR(255), . + PRIMARY KEY (employeeid)); \ No newline at end of file diff --git a/myapp/core/src/main/resources/db/migration/1.0/V0003__PopulateTables.sql b/myapp/core/src/main/resources/db/migration/1.0/V0003__PopulateTables.sql new file mode 100644 index 0000000..a508acd --- /dev/null +++ b/myapp/core/src/main/resources/db/migration/1.0/V0003__PopulateTables.sql @@ -0,0 +1,3 @@ +INSERT INTO EMPLOYEE (id, modificationCounter, employeeid, name, surname,email) VALUES (1, 1, 1, 'John','Doe','john.doe@example.com'); +INSERT INTO EMPLOYEE (id, modificationCounter, employeeid, name, surname,email) VALUES (2, 2, 2, 'Tom','Smith', 'tom.smith@example.com'); +INSERT INTO EMPLOYEE (id, modificationCounter, employeeid, name, surname,email) VALUES (3, 3, 3, 'Joe','Schmoe', 'joe.schmoe@example.com'); \ No newline at end of file diff --git a/myapp/core/src/main/resources/static/index.html b/myapp/core/src/main/resources/static/index.html new file mode 100644 index 0000000..88b7063 --- /dev/null +++ b/myapp/core/src/main/resources/static/index.html @@ -0,0 +1,18 @@ + + + +Welcome + + +

Welcome

+ This is a test! +
+ Services Overview (CXF) +
+
+ +
+ +
+ + \ No newline at end of file diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/ApplicationTest.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/ApplicationTest.java new file mode 100644 index 0000000..49f4546 --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/ApplicationTest.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.general.common.base; + +import javax.inject.Inject; + +import org.junit.jupiter.api.Test; + +import com.devonfw.module.basic.common.api.to.AbstractEto; +import com.devonfw.module.beanmapping.common.api.BeanMapper; + +import com.example.domain.myapp.general.common.base.test.ApplicationComponentTest; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +/** + * This test verifies that {@link com.example.domain.myapp.SpringBootApp} is able to startup. + */ +public class ApplicationTest extends ApplicationComponentTest { + + @Inject + private BeanMapper beanMapper; + + /** Test that {@link it.pkg.SpringBootApp} is able to startup. */ + @Test + public void testContextLoads() { + + // given + Long id = Long.valueOf(4711); + MyEntity entity = new MyEntity(); + entity.setId(id); + // when + MyEto eto = this.beanMapper.map(entity, MyEto.class); + // then + assertThat(eto.getId()).isEqualTo(id); + assertThat(eto.getModificationCounter()).isEqualTo(0); + // and when + entity.setModificationCounter(5); + // then + assertThat(eto.getModificationCounter()).isEqualTo(5); + } + + /** Dummy entity for testing. */ + public static class MyEntity extends ApplicationPersistenceEntity { + private static final long serialVersionUID = 1L; + } + + /** Dummy ETO for testing. */ + public static class MyEto extends AbstractEto { + private static final long serialVersionUID = 1L; + } +} \ No newline at end of file diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/Devon4jPackageCheckTest.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/Devon4jPackageCheckTest.java new file mode 100644 index 0000000..c556397 --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/Devon4jPackageCheckTest.java @@ -0,0 +1,66 @@ +package com.example.domain.myapp.general.common.base; + +import java.util.HashSet; +import java.util.Set; + +import net.sf.mmm.util.reflect.api.ReflectionUtil; +import net.sf.mmm.util.reflect.base.ReflectionUtilImpl; + +import org.assertj.core.api.SoftAssertions; +import org.junit.jupiter.api.Test; + +import com.devonfw.module.basic.common.api.reflect.Devon4jPackage; +import com.devonfw.module.test.common.base.ModuleTest; + +/** + * This test verifies that the entire code of your code-base is located in {@link Devon4jPackage#isValid() valid Devon4j + * packages}. + */ +public class Devon4jPackageCheckTest extends ModuleTest { + + /** + * Scans all the packages of this application root pacakge namespace. Will verify that these are + * {@link Devon4jPackage#isValid() valid Devon4j packages}. + */ + @Test + public void testPackages() { + + Devon4jPackage pkg = Devon4jPackage.of(Devon4jPackageCheckTest.class); + assertThat(pkg.isValid()).isTrue(); + + ReflectionUtil ru = ReflectionUtilImpl.getInstance(); + Set classNames = ru.findClassNames(getRootPackage2Scan(pkg), true); + String appPackage = pkg.getRoot() + "." + pkg.getApplication(); + Set packages = new HashSet<>(128); + packages.add(appPackage); // allow SpringBootApp, etc. in application package + SoftAssertions assertion = new SoftAssertions(); + for (String className : classNames) { + int lastDot = className.lastIndexOf('.'); + if (lastDot > 0) { + String packageName = className.substring(0, lastDot); + boolean added = packages.add(packageName); + if (added) { + pkg = Devon4jPackage.of(packageName); + if (!pkg.isValid()) { + assertion.assertThat(pkg.isValid()) + .as("package " + packageName + " is invalid (component: " + pkg.getComponent() + ", layer: " + + pkg.getLayer() + ", scope: " + pkg.getScope() + "). Hint contains e.g. " + + className.substring(lastDot + 1)) + .isTrue(); + } + } + } + } + assertion.assertAll(); + } + + /** + * @param pkg the {@link Devon4jPackage} of this test. + * @return the root package to scan for {@link Class}es to get the actual packages to check. + */ + protected String getRootPackage2Scan(Devon4jPackage pkg) { + + return pkg.getRoot() + "." + pkg.getApplication(); + } + +} diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/PermissionCheckTest.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/PermissionCheckTest.java new file mode 100644 index 0000000..9de8eaa --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/PermissionCheckTest.java @@ -0,0 +1,67 @@ +package com.example.domain.myapp.general.common.base; + +import com.devonfw.module.test.common.base.ModuleTest; + +import java.lang.reflect.Method; +import java.util.Set; + +import javax.annotation.security.DenyAll; +import javax.annotation.security.PermitAll; +import javax.annotation.security.RolesAllowed; + +import net.sf.mmm.util.filter.api.Filter; +import net.sf.mmm.util.reflect.api.ReflectionUtil; +import net.sf.mmm.util.reflect.base.ReflectionUtilImpl; + +import org.assertj.core.api.SoftAssertions; +import org.junit.jupiter.api.Test; + +/** + * Tests the permission check in logic layer. + */ +public class PermissionCheckTest extends ModuleTest { + + /** + * Check if all relevant methods in use case implementations have permission checks i.e. {@link RolesAllowed}, + * {@link DenyAll} or {@link PermitAll} annotation is applied. This is only checked for methods that are declared in + * the corresponding interface and thus have the {@link Override} annotations applied. + */ + @Test + public void permissionCheckAnnotationPresent() { + + String packageName = "com.example.domain.myapp"; + Filter filter = new Filter() { + + @Override + public boolean accept(String value) { + + return value.contains(".logic.impl.usecase.Uc") && value.endsWith("Impl"); + } + + }; + ReflectionUtil ru = ReflectionUtilImpl.getInstance(); + Set classNames = ru.findClassNames(packageName, true, filter); + Set> classes = ru.loadClasses(classNames); + SoftAssertions assertions = new SoftAssertions(); + for (Class clazz : classes) { + Method[] methods = clazz.getDeclaredMethods(); + for (Method method : methods) { + Method parentMethod = ru.getParentMethod(method); + if (parentMethod != null) { + Class declaringClass = parentMethod.getDeclaringClass(); + if (declaringClass.isInterface() && declaringClass.getSimpleName().startsWith("Uc")) { + boolean hasAnnotation = false; + if (method.getAnnotation(RolesAllowed.class) != null || method.getAnnotation(DenyAll.class) != null + || method.getAnnotation(PermitAll.class) != null) { + hasAnnotation = true; + } + assertions.assertThat(hasAnnotation) + .as("Method " + method.getName() + " in Class " + clazz.getSimpleName() + " is missing access control") + .isTrue(); + } + } + } + } + assertions.assertAll(); + } +} diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/ApplicationComponentTest.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/ApplicationComponentTest.java new file mode 100644 index 0000000..c356af6 --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/ApplicationComponentTest.java @@ -0,0 +1,22 @@ +package com.example.domain.myapp.general.common.base.test; + +import com.devonfw.module.test.common.base.ComponentDbTest; + +import com.example.domain.myapp.SpringBootApp; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + +/** + * Abstract base class for {@link ComponentTest}s of this application. + */ +@SpringBootTest(classes = { SpringBootApp.class }, webEnvironment = WebEnvironment.MOCK) +public abstract class ApplicationComponentTest extends ComponentDbTest { + + @Override + protected void doTearDown() { + super.doTearDown(); + TestUtil.logout(); + } + +} diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/ApplicationSubsystemTest.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/ApplicationSubsystemTest.java new file mode 100644 index 0000000..25df72b --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/ApplicationSubsystemTest.java @@ -0,0 +1,16 @@ +package com.example.domain.myapp.general.common.base.test; + +import com.devonfw.module.test.common.base.SubsystemDbTest; + +import com.example.domain.myapp.SpringBootApp; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + +/** + * Abstract base class for {@link SubsystemTest}s of this application. + */ +@SpringBootTest(classes = { SpringBootApp.class }, webEnvironment = WebEnvironment.RANDOM_PORT) +public abstract class ApplicationSubsystemTest extends SubsystemDbTest { + +} diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/DbTestHelper.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/DbTestHelper.java new file mode 100644 index 0000000..80fbde1 --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/DbTestHelper.java @@ -0,0 +1,44 @@ +package com.example.domain.myapp.general.common.base.test; + +import javax.inject.Named; + +import org.flywaydb.core.Flyway; + +/** + * This class provides methods for handling the database during testing where resets (and other operations) may be + * necessary. + */ +@Named +public class DbTestHelper { + + private Flyway flyway; + + /** + * The constructor. + * + * @param flyway an instance of type {@link Flyway}. + */ + public DbTestHelper(Flyway flyway) { + super(); + this.flyway = flyway; + } + + /** + * Drops the whole database. + */ + public void dropDatabase() { + + this.flyway.clean(); + } + + /** + * Calls {@link #dropDatabase()} internally, and migrates to the highest available migration (default) or to the + * {@code migrationVersion} specified by {@link #setMigrationVersion(String)}. + */ + public void resetDatabase() { + + dropDatabase(); + this.flyway.migrate(); + } + +} diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/TestUtil.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/TestUtil.java new file mode 100644 index 0000000..313a6c0 --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/base/test/TestUtil.java @@ -0,0 +1,29 @@ +package com.example.domain.myapp.general.common.base.test; + +import org.springframework.security.authentication.TestingAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * This is a utility for testing. It allows to simulate authentication for component testing. + */ +public class TestUtil { + + /** + * @param login the id of the user to run the test as. + * @param permissions the permissions for the test. + */ + public static void login(String login, String... permissions) { + + Authentication authentication = new TestingAuthenticationToken(login, login, permissions); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + + /** + * Logs off any previously logged on user. + */ + public static void logout() { + + SecurityContextHolder.getContext().setAuthentication(null); + } +} diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/impl/config/TestDbConfig.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/impl/config/TestDbConfig.java new file mode 100644 index 0000000..a704aa0 --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/impl/config/TestDbConfig.java @@ -0,0 +1,35 @@ +package com.example.domain.myapp.general.common.impl.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.devonfw.module.test.common.base.clean.TestCleaner; +import com.devonfw.module.test.common.base.clean.TestCleanerImpl; +import com.devonfw.module.test.common.base.clean.TestCleanerPlugin; +import com.devonfw.module.test.common.base.clean.TestCleanerPluginFlyway; + +/** + * {@link Configuration} for Database in JUnit tests. + */ +@Configuration +public class TestDbConfig { + + /** + * @return the {@link TestCleaner}. + */ + @Bean + public TestCleaner testCleaner() { + + return new TestCleanerImpl(); + } + + /** + * @return the {@link TestCleanerPluginFlyway}. + */ + @Bean + public TestCleanerPlugin testCleanerPluginFlyway() { + + return new TestCleanerPluginFlyway(); + } + +} diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/common/impl/config/TestWebSecurityConfig.java b/myapp/core/src/test/java/com/example/domain/myapp/general/common/impl/config/TestWebSecurityConfig.java new file mode 100644 index 0000000..2adaad2 --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/common/impl/config/TestWebSecurityConfig.java @@ -0,0 +1,54 @@ +package com.example.domain.myapp.general.common.impl.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +import com.example.domain.myapp.general.service.impl.config.BaseWebSecurityConfig; +import com.devonfw.module.basic.common.api.config.SpringProfileConstants; + +/** + * This type provides web security configuration for testing purposes. + */ +@Configuration +@EnableWebSecurity +@Profile(SpringProfileConstants.JUNIT) +public class TestWebSecurityConfig extends BaseWebSecurityConfig { + private static Logger LOG = LoggerFactory.getLogger(TestWebSecurityConfig.class); + + /** + * Configure spring security to enable a simple webform-login + a simple rest login. + */ + @Override + public void configure(HttpSecurity http) throws Exception { + + super.configure(http); + http.addFilterBefore(basicAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); + + // Disable CSRF protection in tests for simpler testing of REST services + http.csrf().disable(); + LOG.debug("*** CSRF disabled - this config should only be used in development environment ***"); + } + + /** + * @return {@link BasicAuthenticationFilter}. + * @throws Exception on initialization error. + */ + @Bean + protected BasicAuthenticationFilter basicAuthenticationFilter() throws Exception { + + AuthenticationEntryPoint authenticationEntryPoint = new BasicAuthenticationEntryPoint(); + BasicAuthenticationFilter basicAuthenticationFilter = + new BasicAuthenticationFilter(authenticationManagerBean(), authenticationEntryPoint); + return basicAuthenticationFilter; + } + +} diff --git a/myapp/core/src/test/java/com/example/domain/myapp/general/service/base/test/RestServiceTest.java b/myapp/core/src/test/java/com/example/domain/myapp/general/service/base/test/RestServiceTest.java new file mode 100644 index 0000000..6ec045b --- /dev/null +++ b/myapp/core/src/test/java/com/example/domain/myapp/general/service/base/test/RestServiceTest.java @@ -0,0 +1,67 @@ +package com.example.domain.myapp.general.service.base.test; + +import javax.inject.Inject; + +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + +import com.example.domain.myapp.SpringBootApp; +import com.example.domain.myapp.general.common.base.test.DbTestHelper; +import com.example.domain.myapp.general.common.base.test.TestUtil; + +import com.devonfw.module.test.common.base.SubsystemTest; +import com.devonfw.module.test.common.base.SubsystemDbTest; +import com.devonfw.module.service.common.api.client.ServiceClientFactory; + +/** + * Abstract base class for {@link SubsystemTest}s which runs the tests within a local server.
+ *
+ * The local server's port is randomly assigned. + */ +@SpringBootTest(classes = { SpringBootApp.class }, webEnvironment = WebEnvironment.RANDOM_PORT) +public abstract class RestServiceTest extends SubsystemDbTest { + + /** + * The port of the web server during the test. + */ + @LocalServerPort + protected int port; + + @Inject + private ServiceClientFactory serviceClientFactory; + + @Inject + private DbTestHelper dbTestHelper; + + @Override + protected void doSetUp() { + + super.doSetUp(); + } + + @Override + protected void doTearDown() { + + super.doTearDown(); + TestUtil.logout(); + } + + /** + * @return the {@link DbTestHelper} + */ + protected DbTestHelper getDbTestHelper() { + + return this.dbTestHelper; + } + + + /** + * @return the {@link ServiceClientFactory} + */ + protected ServiceClientFactory getServiceClientFactory() { + + return this.serviceClientFactory; + } + +} diff --git a/myapp/core/src/test/resources/config/application.properties b/myapp/core/src/test/resources/config/application.properties new file mode 100644 index 0000000..921492c --- /dev/null +++ b/myapp/core/src/test/resources/config/application.properties @@ -0,0 +1,13 @@ +# This is the spring boot configuration file for JUnit tests. It will only affect JUnits and is not included into the application. +spring.profiles.active=junit + +# Database and JPA +spring.jpa.database=h2 +spring.datasource.url=jdbc:h2:mem:app; +spring.datasource.password= +spring.datasource.username=sa +spring.jpa.hibernate.ddl-auto=none + +# Flyway for Database Setup and Migrations +spring.flyway.enabled=true +spring.flyway.locations=classpath:db/migration diff --git a/myapp/core/src/test/resources/db/test/V0001__InitDb.sql b/myapp/core/src/test/resources/db/test/V0001__InitDb.sql new file mode 100644 index 0000000..2210438 --- /dev/null +++ b/myapp/core/src/test/resources/db/test/V0001__InitDb.sql @@ -0,0 +1,2 @@ +-- Leave a large ID space reserved for master-data and test-data +CREATE SEQUENCE HIBERNATE_SEQUENCE START WITH 1000000; diff --git a/myapp/pom.xml b/myapp/pom.xml new file mode 100644 index 0000000..6bb6c6b --- /dev/null +++ b/myapp/pom.xml @@ -0,0 +1,528 @@ + + + 4.0.0 + myapp + com.example.domain + ${revision} + pom + ${project.artifactId} + Application based on the devon4j. + + + 2.4.4 + 2021.04.003 + 1.8 + 5.7.1 + UTF-8 + UTF-8 + 2.12.2 + 30.1.1-jre + system + oss + + + + api + core + server + + + + + + + com.fasterxml.jackson + jackson-bom + ${jackson.version} + pom + import + + + + org.junit + junit-bom + ${junit.version} + pom + import + + + + com.google.guava + guava + ${guava.version} + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + com.devonfw.java.boms + devon4j-bom + ${devon4j.version} + pom + import + + + + + + + org.slf4j + slf4j-api + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${project.build.sourceEncoding} + ${java.version} + ${java.version} + + + + + maven-surefire-plugin + + ${devonfw.test.excluded.groups} + + + + + + org.jacoco + jacoco-maven-plugin + + + default-prepare-agent + + prepare-agent + + + + default-report + + report + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + + ${flatten.mode} + + + + flatten + process-test-resources + + flatten + + + + flatten.clean + clean + + clean + + + + + + org.codehaus.mojo + servicedocgen-maven-plugin + + + servicedocgen-generate + prepare-package + + generate + + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-install-plugin + 2.5.2 + + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.2 + + + org.apache.maven.plugins + maven-clean-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + org.apache.maven.plugins + maven-source-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-site-plugin + 3.7.1 + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-changes-plugin + 2.12.1 + + + org.apache.maven.plugins + maven-changelog-plugin + 2.3 + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-jxr-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.1 + + + + true + protected + ${project.reporting.outputEncoding} + ${project.build.sourceEncoding} + true + ${user.dir}/src/main/javadoc/stylesheet.css + none + ${java.version} + JavaDocs for ${project.name} ${project.version} + JavaDocs for ${project.name} ${project.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + ${basedir} + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.22.2 + + + org.apache.maven.plugins + maven-pmd-plugin + 3.9.0 + + ${java.version} + + + + org.apache.maven.plugins + maven-war-plugin + 3.2.3 + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + org.apache.maven.plugins + maven-help-plugin + 3.2.0 + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + org.apache.maven.plugins + maven-archetype-plugin + 3.1.2 + + + org.apache.maven.archetype + archetype-packaging + 3.1.2 + + + org.codehaus.mojo + taglist-maven-plugin + 2.4 + + + org.codehaus.mojo + cobertura-maven-plugin + 2.7 + + + org.codehaus.mojo + flatten-maven-plugin + 1.2.2 + + + org.codehaus.mojo + license-maven-plugin + 1.20 + + ${project.build.directory}/generated-resources + true + true + true + true + + Apache Software License, Version 2.0|The Apache Software License, Version 2.0|Apache + 2.0|Apache License, Version 2.0 + + + + + org.codehaus.mojo + servicedocgen-maven-plugin + 1.0.0 + + + + ${servicedoc.info.title} + ${servicedoc.info.description} + + ${servicedoc.host} + ${servicedoc.port} + ${servicedoc.basePath} + + http + + + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + 3.7.0.1746 + + + org.jacoco + jacoco-maven-plugin + 0.8.5 + + + org.owasp + dependency-check-maven + 5.3.2 + + + com.github.spotbugs + spotbugs-maven-plugin + 3.1.12.2 + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + + + + + moduletest + + component,subsystem,system + + + + componenttest + + subsystem,system + + + + subsystemtest + + system + + + + systemtest + + none + + + + security + + + + org.owasp + dependency-check-maven + + 8 + + + + + check + + + + + + + + + licenses + + + + org.codehaus.mojo + license-maven-plugin + + + aggregate-add-third-party + generate-resources + + aggregate-add-third-party + + + + + aggregate-download-licenses + generate-resources + + aggregate-download-licenses + + + + + + + + + + eclipse + + + eclipse.application + + + + eclipse-target + + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + false + + + + org.apache.maven.plugins + maven-jxr-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.codehaus.mojo + taglist-maven-plugin + + + TODO + @todo + FIXME + @deprecated + REVIEW + + + + + org.owasp + dependency-check-maven + + false + + + + + aggregate + check + + + + + + org.codehaus.mojo + servicedocgen-maven-plugin + + + org.codehaus.mojo + license-maven-plugin + + + + third-party-report + aggregate-third-party-report + + + + + + + + diff --git a/myapp/server/pom.xml b/myapp/server/pom.xml new file mode 100644 index 0000000..4cfd050 --- /dev/null +++ b/myapp/server/pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + com.example.domain + myapp + ${revision} + + myapp-server + war + ${project.artifactId} + Server for the myapp application - a simple example based on devon4j. + + + + ${project.groupId} + myapp-core + ${project.version} + + + + com.devonfw.java.modules + devon4j-test-jpa + test + + + + + + jsclient + + + false + + + + + org.codehaus.mojo + exec-maven-plugin + + + npm-install + generate-sources + + exec + + + npm + + install + + ${js.client.dir} + + + + gulp-clean + generate-sources + + exec + + + gulp + + clean + + ${js.client.dir} + + + + gulp-build + generate-sources + + exec + + + gulp + + build:dist + + ${js.client.dir} + + + + gulp-test + test + + exec + + + gulp + + test + + ${js.client.dir} + + + + + + org.apache.maven.plugins + maven-war-plugin + + WEB-INF/classes/config/application.properties + ${project.artifactId} + false + + + + + + + + + + + ${project.basedir}/src/main/resources + + + ${js.client.dir}/dist + static + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.example.domain.myapp.SpringBootApp + bootified + ${project.artifactId} + + + + + repackage + + + + + + + + + diff --git a/myapp/server/src/main/resources/logback.xml b/myapp/server/src/main/resources/logback.xml new file mode 100644 index 0000000..e509fa0 --- /dev/null +++ b/myapp/server/src/main/resources/logback.xml @@ -0,0 +1,32 @@ + + + + + + false + correlationId + + timestamp + [ignore] + [ignore] + +      {"appname":"myapp"} + UTC + + + + + + + + + + + + + + + + + + diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeDetailResponseDtoSchemaEntity.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeDetailResponseDtoSchemaEntity.java new file mode 100644 index 0000000..e8607bd --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeDetailResponseDtoSchemaEntity.java @@ -0,0 +1,77 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeDetailResponseDtoSchema; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + +/** + * Entity definiton of Employee + */ +@Entity +@javax.persistence.Table(name = "EmployeeDetailResponseDtoSchema") +public class EmployeeDetailResponseDtoSchemaEntity extends ApplicationPersistenceEntity implements EmployeeDetailResponseDtoSchema { + + private static final long serialVersionUID = 1L; + + private long modificationCounter; + private long employeeId; + @Size(max = 30, min = 3) + private String name; + @Size(max = 100, min = 3) + private String surname; + @Size(max = 100, min = 3) + private String email; + + public long getModificationCounter() { + return this.modificationCounter; + } + + public void setModificationCounter(long modificationCounter) { + this.modificationCounter = modificationCounter; + } + + + public long getEmployeeId() { + return this.employeeId; + } + + public void setEmployeeId(long employeeId) { + this.employeeId = employeeId; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return this.surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeInsertRequestDtoSchemaEntity.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeInsertRequestDtoSchemaEntity.java new file mode 100644 index 0000000..8753891 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeInsertRequestDtoSchemaEntity.java @@ -0,0 +1,58 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeInsertRequestDtoSchema; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + +/** + * Entity definiton of Employee + */ +@Entity +@javax.persistence.Table(name = "EmployeeInsertRequestDtoSchema") +public class EmployeeInsertRequestDtoSchemaEntity extends ApplicationPersistenceEntity implements EmployeeInsertRequestDtoSchema { + + private static final long serialVersionUID = 1L; + + @Size(max = 30, min = 3) + private String name; + @Size(max = 100, min = 3) + private String surname; + @Size(max = 100, min = 3) + private String email; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return this.surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeInsertResponseDtoSchemaEntity.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeInsertResponseDtoSchemaEntity.java new file mode 100644 index 0000000..2d0b324 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeInsertResponseDtoSchemaEntity.java @@ -0,0 +1,68 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeInsertResponseDtoSchema; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + +/** + * Entity definiton of Employee + */ +@Entity +@javax.persistence.Table(name = "EmployeeInsertResponseDtoSchema") +public class EmployeeInsertResponseDtoSchemaEntity extends ApplicationPersistenceEntity implements EmployeeInsertResponseDtoSchema { + + private static final long serialVersionUID = 1L; + + private long modificationCounter; + @Size(max = 100, min = 3) + private String name; + @Size(max = 100, min = 3) + private String surname; + @Size(max = 100, min = 3) + private String email; + + public long getModificationCounter() { + return this.modificationCounter; + } + + public void setModificationCounter(long modificationCounter) { + this.modificationCounter = modificationCounter; + } + + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return this.surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListContentResponseDtoSchemaEntity.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListContentResponseDtoSchemaEntity.java new file mode 100644 index 0000000..d5b8400 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListContentResponseDtoSchemaEntity.java @@ -0,0 +1,77 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeListContentResponseDtoSchema; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + +/** + * Entity definiton of Employee + */ +@Entity +@javax.persistence.Table(name = "EmployeeListContentResponseDtoSchema") +public class EmployeeListContentResponseDtoSchemaEntity extends ApplicationPersistenceEntity implements EmployeeListContentResponseDtoSchema { + + private static final long serialVersionUID = 1L; + + private long modificationCounter; + private long employeeId; + @Size(max = 100, min = 3) + private String name; + @Size(max = 100, min = 3) + private String surname; + @Size(max = 100, min = 3) + private String email; + + public long getModificationCounter() { + return this.modificationCounter; + } + + public void setModificationCounter(long modificationCounter) { + this.modificationCounter = modificationCounter; + } + + + public long getEmployeeId() { + return this.employeeId; + } + + public void setEmployeeId(long employeeId) { + this.employeeId = employeeId; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return this.surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListRequestDtoSchemaEntity.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListRequestDtoSchemaEntity.java new file mode 100644 index 0000000..4941463 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListRequestDtoSchemaEntity.java @@ -0,0 +1,77 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeListRequestDtoSchema; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + +/** + * Entity definiton of Employee + */ +@Entity +@javax.persistence.Table(name = "EmployeeListRequestDtoSchema") +public class EmployeeListRequestDtoSchemaEntity extends ApplicationPersistenceEntity implements EmployeeListRequestDtoSchema { + + private static final long serialVersionUID = 1L; + + @Size(max = 30, min = 3) + private String employeeId; + @Size(max = 30, min = 3) + private String name; + @Size(max = 100, min = 3) + private String surname; + @Size(max = 100, min = 3) + private String email; + private void pageable; + + public String getEmployeeId() { + return this.employeeId; + } + + public void setEmployeeId(String employeeId) { + this.employeeId = employeeId; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return this.surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + public void getPageable() { + return this.pageable; + } + + public void setPageable(void pageable) { + this.pageable = pageable; + } + + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListResponseDtoSchemaEntity.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListResponseDtoSchemaEntity.java new file mode 100644 index 0000000..63f49e3 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/EmployeeListResponseDtoSchemaEntity.java @@ -0,0 +1,55 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeListResponseDtoSchema; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + +/** + * Entity definiton of Employee + */ +@Entity +@javax.persistence.Table(name = "EmployeeListResponseDtoSchema") +public class EmployeeListResponseDtoSchemaEntity extends ApplicationPersistenceEntity implements EmployeeListResponseDtoSchema { + + private static final long serialVersionUID = 1L; + + private List content; + private void pageable; + private long totalElements; + + public void setContent(List content) { + this.content = content; + } + + public List getContent() { + return this.content; + } + + public void getPageable() { + return this.pageable; + } + + public void setPageable(void pageable) { + this.pageable = pageable; + } + + public long getTotalElements() { + return this.totalElements; + } + + public void setTotalElements(long totalElements) { + this.totalElements = totalElements; + } + + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/PageableDtoSchemaEntity.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/PageableDtoSchemaEntity.java new file mode 100644 index 0000000..5460d2d --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/PageableDtoSchemaEntity.java @@ -0,0 +1,55 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api; + +import com.example.domain.myapp.employeemanagement.common.api.PageableDtoSchema; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + +/** + * Entity definition of Pageable + */ +@Entity +@javax.persistence.Table(name = "PageableDtoSchema") +public class PageableDtoSchemaEntity extends ApplicationPersistenceEntity implements PageableDtoSchema { + + private static final long serialVersionUID = 1L; + + private long pageSize; + private long pageNumber; + private List sort; + + public long getPageSize() { + return this.pageSize; + } + + public void setPageSize(long pageSize) { + this.pageSize = pageSize; + } + + public long getPageNumber() { + return this.pageNumber; + } + + public void setPageNumber(long pageNumber) { + this.pageNumber = pageNumber; + } + + public void setSort(List sort) { + this.sort = sort; + } + + public List getSort() { + return this.sort; + } + + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/PageableSortDtoSchemaEntity.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/PageableSortDtoSchemaEntity.java new file mode 100644 index 0000000..28bf2c7 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/PageableSortDtoSchemaEntity.java @@ -0,0 +1,48 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api; + +import com.example.domain.myapp.employeemanagement.common.api.PageableSortDtoSchema; +import com.example.domain.myapp.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + +/** + * Entity definition of PageSort + */ +@Entity +@javax.persistence.Table(name = "PageableSortDtoSchema") +public class PageableSortDtoSchemaEntity extends ApplicationPersistenceEntity implements PageableSortDtoSchema { + + private static final long serialVersionUID = 1L; + + @Size(max = 100, min = 3) + private String property; + @Size(max = 100, min = 3) + private String direction; + + public String getProperty() { + return this.property; + } + + public void setProperty(String property) { + this.property = property; + } + + public String getDirection() { + return this.direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeDetailResponseDtoSchemaRepository.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeDetailResponseDtoSchemaRepository.java new file mode 100644 index 0000000..0cbfcd1 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeDetailResponseDtoSchemaRepository.java @@ -0,0 +1,126 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeDetailResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeDetailResponseDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeDetailResponseDtoSchemaSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link EmployeeDetailResponseDtoSchemaEntity} + */ +public interface EmployeeDetailResponseDtoSchemaRepository extends DefaultRepository { + + /** + * @param criteria the {@link EmployeeDetailResponseDtoSchemaSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link EmployeeDetailResponseDtoSchemaEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(EmployeeDetailResponseDtoSchemaSearchCriteriaTo criteria) { + + EmployeeDetailResponseDtoSchemaEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +Long modificationCounter = criteria.getModificationCounter(); +if (modificationCounter != null) { +query.where($(alias.getModificationCounter()).eq(modificationCounter)); +}Long id = criteria.getId(); +if (id != null) { +query.where($(alias.getId()).eq(id)); +}Long employeeId = criteria.getEmployeeId(); +if (employeeId != null) { +query.where($(alias.getEmployeeId()).eq(employeeId)); +}String name = criteria.getName(); +if (name != null && !name.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getName()), name, criteria.getNameOption()); +}String surname = criteria.getSurname(); +if (surname != null && !surname.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getSurname()), surname, criteria.getSurnameOption()); +}String email = criteria.getEmail(); +if (email != null && !email.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getEmail()), email, criteria.getEmailOption()); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, EmployeeDetailResponseDtoSchemaEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "modificationCounter": + if (next.isAscending()) { + query.orderBy($(alias.getModificationCounter()).asc()); + } else { + query.orderBy($(alias.getModificationCounter()).desc()); + } + break; + case "id": + if (next.isAscending()) { + query.orderBy($(alias.getId()).asc()); + } else { + query.orderBy($(alias.getId()).desc()); + } + break; + case "employeeId": + if (next.isAscending()) { + query.orderBy($(alias.getEmployeeId()).asc()); + } else { + query.orderBy($(alias.getEmployeeId()).desc()); + } + break; + case "name": + if (next.isAscending()) { + query.orderBy($(alias.getName()).asc()); + } else { + query.orderBy($(alias.getName()).desc()); + } + break; + case "surname": + if (next.isAscending()) { + query.orderBy($(alias.getSurname()).asc()); + } else { + query.orderBy($(alias.getSurname()).desc()); + } + break; + case "email": + if (next.isAscending()) { + query.orderBy($(alias.getEmail()).asc()); + } else { + query.orderBy($(alias.getEmail()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeInsertRequestDtoSchemaRepository.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeInsertRequestDtoSchemaRepository.java new file mode 100644 index 0000000..49ab115 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeInsertRequestDtoSchemaRepository.java @@ -0,0 +1,96 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeInsertRequestDtoSchema; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeInsertRequestDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeInsertRequestDtoSchemaSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link EmployeeInsertRequestDtoSchemaEntity} + */ +public interface EmployeeInsertRequestDtoSchemaRepository extends DefaultRepository { + + /** + * @param criteria the {@link EmployeeInsertRequestDtoSchemaSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link EmployeeInsertRequestDtoSchemaEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(EmployeeInsertRequestDtoSchemaSearchCriteriaTo criteria) { + + EmployeeInsertRequestDtoSchemaEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +String name = criteria.getName(); +if (name != null && !name.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getName()), name, criteria.getNameOption()); +}String surname = criteria.getSurname(); +if (surname != null && !surname.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getSurname()), surname, criteria.getSurnameOption()); +}String email = criteria.getEmail(); +if (email != null && !email.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getEmail()), email, criteria.getEmailOption()); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, EmployeeInsertRequestDtoSchemaEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "name": + if (next.isAscending()) { + query.orderBy($(alias.getName()).asc()); + } else { + query.orderBy($(alias.getName()).desc()); + } + break; + case "surname": + if (next.isAscending()) { + query.orderBy($(alias.getSurname()).asc()); + } else { + query.orderBy($(alias.getSurname()).desc()); + } + break; + case "email": + if (next.isAscending()) { + query.orderBy($(alias.getEmail()).asc()); + } else { + query.orderBy($(alias.getEmail()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeInsertResponseDtoSchemaRepository.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeInsertResponseDtoSchemaRepository.java new file mode 100644 index 0000000..6e88bd0 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeInsertResponseDtoSchemaRepository.java @@ -0,0 +1,116 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeInsertResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeInsertResponseDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeInsertResponseDtoSchemaSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link EmployeeInsertResponseDtoSchemaEntity} + */ +public interface EmployeeInsertResponseDtoSchemaRepository extends DefaultRepository { + + /** + * @param criteria the {@link EmployeeInsertResponseDtoSchemaSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link EmployeeInsertResponseDtoSchemaEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(EmployeeInsertResponseDtoSchemaSearchCriteriaTo criteria) { + + EmployeeInsertResponseDtoSchemaEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +Long modificationCounter = criteria.getModificationCounter(); +if (modificationCounter != null) { +query.where($(alias.getModificationCounter()).eq(modificationCounter)); +}Long id = criteria.getId(); +if (id != null) { +query.where($(alias.getId()).eq(id)); +}String name = criteria.getName(); +if (name != null && !name.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getName()), name, criteria.getNameOption()); +}String surname = criteria.getSurname(); +if (surname != null && !surname.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getSurname()), surname, criteria.getSurnameOption()); +}String email = criteria.getEmail(); +if (email != null && !email.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getEmail()), email, criteria.getEmailOption()); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, EmployeeInsertResponseDtoSchemaEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "modificationCounter": + if (next.isAscending()) { + query.orderBy($(alias.getModificationCounter()).asc()); + } else { + query.orderBy($(alias.getModificationCounter()).desc()); + } + break; + case "id": + if (next.isAscending()) { + query.orderBy($(alias.getId()).asc()); + } else { + query.orderBy($(alias.getId()).desc()); + } + break; + case "name": + if (next.isAscending()) { + query.orderBy($(alias.getName()).asc()); + } else { + query.orderBy($(alias.getName()).desc()); + } + break; + case "surname": + if (next.isAscending()) { + query.orderBy($(alias.getSurname()).asc()); + } else { + query.orderBy($(alias.getSurname()).desc()); + } + break; + case "email": + if (next.isAscending()) { + query.orderBy($(alias.getEmail()).asc()); + } else { + query.orderBy($(alias.getEmail()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListContentResponseDtoSchemaRepository.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListContentResponseDtoSchemaRepository.java new file mode 100644 index 0000000..012f535 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListContentResponseDtoSchemaRepository.java @@ -0,0 +1,126 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeListContentResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListContentResponseDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListContentResponseDtoSchemaSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link EmployeeListContentResponseDtoSchemaEntity} + */ +public interface EmployeeListContentResponseDtoSchemaRepository extends DefaultRepository { + + /** + * @param criteria the {@link EmployeeListContentResponseDtoSchemaSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link EmployeeListContentResponseDtoSchemaEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(EmployeeListContentResponseDtoSchemaSearchCriteriaTo criteria) { + + EmployeeListContentResponseDtoSchemaEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +Long modificationCounter = criteria.getModificationCounter(); +if (modificationCounter != null) { +query.where($(alias.getModificationCounter()).eq(modificationCounter)); +}Long id = criteria.getId(); +if (id != null) { +query.where($(alias.getId()).eq(id)); +}Long employeeId = criteria.getEmployeeId(); +if (employeeId != null) { +query.where($(alias.getEmployeeId()).eq(employeeId)); +}String name = criteria.getName(); +if (name != null && !name.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getName()), name, criteria.getNameOption()); +}String surname = criteria.getSurname(); +if (surname != null && !surname.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getSurname()), surname, criteria.getSurnameOption()); +}String email = criteria.getEmail(); +if (email != null && !email.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getEmail()), email, criteria.getEmailOption()); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, EmployeeListContentResponseDtoSchemaEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "modificationCounter": + if (next.isAscending()) { + query.orderBy($(alias.getModificationCounter()).asc()); + } else { + query.orderBy($(alias.getModificationCounter()).desc()); + } + break; + case "id": + if (next.isAscending()) { + query.orderBy($(alias.getId()).asc()); + } else { + query.orderBy($(alias.getId()).desc()); + } + break; + case "employeeId": + if (next.isAscending()) { + query.orderBy($(alias.getEmployeeId()).asc()); + } else { + query.orderBy($(alias.getEmployeeId()).desc()); + } + break; + case "name": + if (next.isAscending()) { + query.orderBy($(alias.getName()).asc()); + } else { + query.orderBy($(alias.getName()).desc()); + } + break; + case "surname": + if (next.isAscending()) { + query.orderBy($(alias.getSurname()).asc()); + } else { + query.orderBy($(alias.getSurname()).desc()); + } + break; + case "email": + if (next.isAscending()) { + query.orderBy($(alias.getEmail()).asc()); + } else { + query.orderBy($(alias.getEmail()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListRequestDtoSchemaRepository.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListRequestDtoSchemaRepository.java new file mode 100644 index 0000000..e90ac03 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListRequestDtoSchemaRepository.java @@ -0,0 +1,116 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeListRequestDtoSchema; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListRequestDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListRequestDtoSchemaSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link EmployeeListRequestDtoSchemaEntity} + */ +public interface EmployeeListRequestDtoSchemaRepository extends DefaultRepository { + + /** + * @param criteria the {@link EmployeeListRequestDtoSchemaSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link EmployeeListRequestDtoSchemaEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(EmployeeListRequestDtoSchemaSearchCriteriaTo criteria) { + + EmployeeListRequestDtoSchemaEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +String employeeId = criteria.getEmployeeId(); +if (employeeId != null && !employeeId.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getEmployeeId()), employeeId, criteria.getEmployeeIdOption()); +}String name = criteria.getName(); +if (name != null && !name.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getName()), name, criteria.getNameOption()); +}String surname = criteria.getSurname(); +if (surname != null && !surname.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getSurname()), surname, criteria.getSurnameOption()); +}String email = criteria.getEmail(); +if (email != null && !email.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getEmail()), email, criteria.getEmailOption()); +}Void pageable = criteria.getPageable(); +if (pageable != null) { +query.where($(alias.getPageable()).eq(pageable)); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, EmployeeListRequestDtoSchemaEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "employeeId": + if (next.isAscending()) { + query.orderBy($(alias.getEmployeeId()).asc()); + } else { + query.orderBy($(alias.getEmployeeId()).desc()); + } + break; + case "name": + if (next.isAscending()) { + query.orderBy($(alias.getName()).asc()); + } else { + query.orderBy($(alias.getName()).desc()); + } + break; + case "surname": + if (next.isAscending()) { + query.orderBy($(alias.getSurname()).asc()); + } else { + query.orderBy($(alias.getSurname()).desc()); + } + break; + case "email": + if (next.isAscending()) { + query.orderBy($(alias.getEmail()).asc()); + } else { + query.orderBy($(alias.getEmail()).desc()); + } + break; + case "pageable": + if (next.isAscending()) { + query.orderBy($(alias.getPageable()).asc()); + } else { + query.orderBy($(alias.getPageable()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListResponseDtoSchemaRepository.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListResponseDtoSchemaRepository.java new file mode 100644 index 0000000..9bbf24d --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/EmployeeListResponseDtoSchemaRepository.java @@ -0,0 +1,86 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.example.domain.myapp.employeemanagement.common.api.EmployeeListResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListResponseDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListResponseDtoSchemaSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link EmployeeListResponseDtoSchemaEntity} + */ +public interface EmployeeListResponseDtoSchemaRepository extends DefaultRepository { + + /** + * @param criteria the {@link EmployeeListResponseDtoSchemaSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link EmployeeListResponseDtoSchemaEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(EmployeeListResponseDtoSchemaSearchCriteriaTo criteria) { + + EmployeeListResponseDtoSchemaEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +Void pageable = criteria.getPageable(); +if (pageable != null) { +query.where($(alias.getPageable()).eq(pageable)); +}Long totalElements = criteria.getTotalElements(); +if (totalElements != null) { +query.where($(alias.getTotalElements()).eq(totalElements)); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, EmployeeListResponseDtoSchemaEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "pageable": + if (next.isAscending()) { + query.orderBy($(alias.getPageable()).asc()); + } else { + query.orderBy($(alias.getPageable()).desc()); + } + break; + case "totalElements": + if (next.isAscending()) { + query.orderBy($(alias.getTotalElements()).asc()); + } else { + query.orderBy($(alias.getTotalElements()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/PageableDtoSchemaRepository.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/PageableDtoSchemaRepository.java new file mode 100644 index 0000000..26a4c1a --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/PageableDtoSchemaRepository.java @@ -0,0 +1,86 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.example.domain.myapp.employeemanagement.common.api.PageableDtoSchema; +import com.example.domain.myapp.employeemanagement.dataaccess.api.PageableDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.PageableDtoSchemaSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link PageableDtoSchemaEntity} + */ +public interface PageableDtoSchemaRepository extends DefaultRepository { + + /** + * @param criteria the {@link PageableDtoSchemaSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link PageableDtoSchemaEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(PageableDtoSchemaSearchCriteriaTo criteria) { + + PageableDtoSchemaEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +Long pageSize = criteria.getPageSize(); +if (pageSize != null) { +query.where($(alias.getPageSize()).eq(pageSize)); +}Long pageNumber = criteria.getPageNumber(); +if (pageNumber != null) { +query.where($(alias.getPageNumber()).eq(pageNumber)); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, PageableDtoSchemaEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "pageSize": + if (next.isAscending()) { + query.orderBy($(alias.getPageSize()).asc()); + } else { + query.orderBy($(alias.getPageSize()).desc()); + } + break; + case "pageNumber": + if (next.isAscending()) { + query.orderBy($(alias.getPageNumber()).asc()); + } else { + query.orderBy($(alias.getPageNumber()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/PageableSortDtoSchemaRepository.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/PageableSortDtoSchemaRepository.java new file mode 100644 index 0000000..6b1b2c8 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/dataaccess/api/repo/PageableSortDtoSchemaRepository.java @@ -0,0 +1,86 @@ +package com.example.domain.myapp.employeemanagement.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.example.domain.myapp.employeemanagement.common.api.PageableSortDtoSchema; +import com.example.domain.myapp.employeemanagement.dataaccess.api.PageableSortDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.PageableSortDtoSchemaSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link PageableSortDtoSchemaEntity} + */ +public interface PageableSortDtoSchemaRepository extends DefaultRepository { + + /** + * @param criteria the {@link PageableSortDtoSchemaSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link PageableSortDtoSchemaEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(PageableSortDtoSchemaSearchCriteriaTo criteria) { + + PageableSortDtoSchemaEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +String property = criteria.getProperty(); +if (property != null && !property.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getProperty()), property, criteria.getPropertyOption()); +}String direction = criteria.getDirection(); +if (direction != null && !direction.isEmpty()) { +QueryUtil.get().whereString(query, $(alias.getDirection()), direction, criteria.getDirectionOption()); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, PageableSortDtoSchemaEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "property": + if (next.isAscending()) { + query.orderBy($(alias.getProperty()).asc()); + } else { + query.orderBy($(alias.getProperty()).desc()); + } + break; + case "direction": + if (next.isAscending()) { + query.orderBy($(alias.getDirection()).asc()); + } else { + query.orderBy($(alias.getDirection()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeDetailResponseDtoSchemaUc.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeDetailResponseDtoSchemaUc.java new file mode 100644 index 0000000..a56084e --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeDetailResponseDtoSchemaUc.java @@ -0,0 +1,26 @@ +package com.example.domain.myapp.employeemanagement.logic.base.usecase; + +import com.example.domain.myapp.general.logic.base.AbstractUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.repo.EmployeeDetailResponseDtoSchemaRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for EmployeeDetailResponseDtoSchemas, which provides access to the commonly necessary data access objects. + */ +public class AbstractEmployeeDetailResponseDtoSchemaUc extends AbstractUc { + + /** @see #getEmployeeDetailResponseDtoSchemaRepository() */ + @Inject + private EmployeeDetailResponseDtoSchemaRepository employeeDetailResponseDtoSchemaRepository; + + /** + * Returns the field 'employeeDetailResponseDtoSchemaRepository'. + * @return the {@link EmployeeDetailResponseDtoSchemaRepository} instance. + */ + public EmployeeDetailResponseDtoSchemaRepository getEmployeeDetailResponseDtoSchemaRepository() { + + return this.employeeDetailResponseDtoSchemaRepository; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeInsertRequestDtoSchemaUc.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeInsertRequestDtoSchemaUc.java new file mode 100644 index 0000000..e08babc --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeInsertRequestDtoSchemaUc.java @@ -0,0 +1,26 @@ +package com.example.domain.myapp.employeemanagement.logic.base.usecase; + +import com.example.domain.myapp.general.logic.base.AbstractUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.repo.EmployeeInsertRequestDtoSchemaRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for EmployeeInsertRequestDtoSchemas, which provides access to the commonly necessary data access objects. + */ +public class AbstractEmployeeInsertRequestDtoSchemaUc extends AbstractUc { + + /** @see #getEmployeeInsertRequestDtoSchemaRepository() */ + @Inject + private EmployeeInsertRequestDtoSchemaRepository employeeInsertRequestDtoSchemaRepository; + + /** + * Returns the field 'employeeInsertRequestDtoSchemaRepository'. + * @return the {@link EmployeeInsertRequestDtoSchemaRepository} instance. + */ + public EmployeeInsertRequestDtoSchemaRepository getEmployeeInsertRequestDtoSchemaRepository() { + + return this.employeeInsertRequestDtoSchemaRepository; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeInsertResponseDtoSchemaUc.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeInsertResponseDtoSchemaUc.java new file mode 100644 index 0000000..46d312f --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeInsertResponseDtoSchemaUc.java @@ -0,0 +1,26 @@ +package com.example.domain.myapp.employeemanagement.logic.base.usecase; + +import com.example.domain.myapp.general.logic.base.AbstractUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.repo.EmployeeInsertResponseDtoSchemaRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for EmployeeInsertResponseDtoSchemas, which provides access to the commonly necessary data access objects. + */ +public class AbstractEmployeeInsertResponseDtoSchemaUc extends AbstractUc { + + /** @see #getEmployeeInsertResponseDtoSchemaRepository() */ + @Inject + private EmployeeInsertResponseDtoSchemaRepository employeeInsertResponseDtoSchemaRepository; + + /** + * Returns the field 'employeeInsertResponseDtoSchemaRepository'. + * @return the {@link EmployeeInsertResponseDtoSchemaRepository} instance. + */ + public EmployeeInsertResponseDtoSchemaRepository getEmployeeInsertResponseDtoSchemaRepository() { + + return this.employeeInsertResponseDtoSchemaRepository; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListContentResponseDtoSchemaUc.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListContentResponseDtoSchemaUc.java new file mode 100644 index 0000000..99ad031 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListContentResponseDtoSchemaUc.java @@ -0,0 +1,26 @@ +package com.example.domain.myapp.employeemanagement.logic.base.usecase; + +import com.example.domain.myapp.general.logic.base.AbstractUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.repo.EmployeeListContentResponseDtoSchemaRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for EmployeeListContentResponseDtoSchemas, which provides access to the commonly necessary data access objects. + */ +public class AbstractEmployeeListContentResponseDtoSchemaUc extends AbstractUc { + + /** @see #getEmployeeListContentResponseDtoSchemaRepository() */ + @Inject + private EmployeeListContentResponseDtoSchemaRepository employeeListContentResponseDtoSchemaRepository; + + /** + * Returns the field 'employeeListContentResponseDtoSchemaRepository'. + * @return the {@link EmployeeListContentResponseDtoSchemaRepository} instance. + */ + public EmployeeListContentResponseDtoSchemaRepository getEmployeeListContentResponseDtoSchemaRepository() { + + return this.employeeListContentResponseDtoSchemaRepository; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListRequestDtoSchemaUc.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListRequestDtoSchemaUc.java new file mode 100644 index 0000000..ba3de4a --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListRequestDtoSchemaUc.java @@ -0,0 +1,26 @@ +package com.example.domain.myapp.employeemanagement.logic.base.usecase; + +import com.example.domain.myapp.general.logic.base.AbstractUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.repo.EmployeeListRequestDtoSchemaRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for EmployeeListRequestDtoSchemas, which provides access to the commonly necessary data access objects. + */ +public class AbstractEmployeeListRequestDtoSchemaUc extends AbstractUc { + + /** @see #getEmployeeListRequestDtoSchemaRepository() */ + @Inject + private EmployeeListRequestDtoSchemaRepository employeeListRequestDtoSchemaRepository; + + /** + * Returns the field 'employeeListRequestDtoSchemaRepository'. + * @return the {@link EmployeeListRequestDtoSchemaRepository} instance. + */ + public EmployeeListRequestDtoSchemaRepository getEmployeeListRequestDtoSchemaRepository() { + + return this.employeeListRequestDtoSchemaRepository; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListResponseDtoSchemaUc.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListResponseDtoSchemaUc.java new file mode 100644 index 0000000..30a1e57 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractEmployeeListResponseDtoSchemaUc.java @@ -0,0 +1,26 @@ +package com.example.domain.myapp.employeemanagement.logic.base.usecase; + +import com.example.domain.myapp.general.logic.base.AbstractUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.repo.EmployeeListResponseDtoSchemaRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for EmployeeListResponseDtoSchemas, which provides access to the commonly necessary data access objects. + */ +public class AbstractEmployeeListResponseDtoSchemaUc extends AbstractUc { + + /** @see #getEmployeeListResponseDtoSchemaRepository() */ + @Inject + private EmployeeListResponseDtoSchemaRepository employeeListResponseDtoSchemaRepository; + + /** + * Returns the field 'employeeListResponseDtoSchemaRepository'. + * @return the {@link EmployeeListResponseDtoSchemaRepository} instance. + */ + public EmployeeListResponseDtoSchemaRepository getEmployeeListResponseDtoSchemaRepository() { + + return this.employeeListResponseDtoSchemaRepository; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractPageableDtoSchemaUc.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractPageableDtoSchemaUc.java new file mode 100644 index 0000000..b2783c5 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractPageableDtoSchemaUc.java @@ -0,0 +1,26 @@ +package com.example.domain.myapp.employeemanagement.logic.base.usecase; + +import com.example.domain.myapp.general.logic.base.AbstractUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.repo.PageableDtoSchemaRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for PageableDtoSchemas, which provides access to the commonly necessary data access objects. + */ +public class AbstractPageableDtoSchemaUc extends AbstractUc { + + /** @see #getPageableDtoSchemaRepository() */ + @Inject + private PageableDtoSchemaRepository pageableDtoSchemaRepository; + + /** + * Returns the field 'pageableDtoSchemaRepository'. + * @return the {@link PageableDtoSchemaRepository} instance. + */ + public PageableDtoSchemaRepository getPageableDtoSchemaRepository() { + + return this.pageableDtoSchemaRepository; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractPageableSortDtoSchemaUc.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractPageableSortDtoSchemaUc.java new file mode 100644 index 0000000..4fc91d4 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/base/usecase/AbstractPageableSortDtoSchemaUc.java @@ -0,0 +1,26 @@ +package com.example.domain.myapp.employeemanagement.logic.base.usecase; + +import com.example.domain.myapp.general.logic.base.AbstractUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.repo.PageableSortDtoSchemaRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for PageableSortDtoSchemas, which provides access to the commonly necessary data access objects. + */ +public class AbstractPageableSortDtoSchemaUc extends AbstractUc { + + /** @see #getPageableSortDtoSchemaRepository() */ + @Inject + private PageableSortDtoSchemaRepository pageableSortDtoSchemaRepository; + + /** + * Returns the field 'pageableSortDtoSchemaRepository'. + * @return the {@link PageableSortDtoSchemaRepository} instance. + */ + public PageableSortDtoSchemaRepository getPageableSortDtoSchemaRepository() { + + return this.pageableSortDtoSchemaRepository; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeDetailResponseDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeDetailResponseDtoSchemaImpl.java new file mode 100644 index 0000000..3058d12 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeDetailResponseDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeDetailResponseDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcFindEmployeeDetailResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeDetailResponseDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeDetailResponseDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeDetailResponseDtoSchemaSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting EmployeeDetailResponseDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcFindEmployeeDetailResponseDtoSchemaImpl extends AbstractEmployeeDetailResponseDtoSchemaUc implements UcFindEmployeeDetailResponseDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindEmployeeDetailResponseDtoSchemaImpl.class); + + + @Override + public EmployeeDetailResponseDtoSchemaEto findEmployeeDetailResponseDtoSchema(long id) { + LOG.debug("Get EmployeeDetailResponseDtoSchema with id {} from database.", id); + Optional foundEntity = getEmployeeDetailResponseDtoSchemaRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), EmployeeDetailResponseDtoSchemaEto.class); + else + return null; + } + + @Override + public Page findEmployeeDetailResponseDtoSchemas(EmployeeDetailResponseDtoSchemaSearchCriteriaTo criteria) { + Page employeedetailresponsedtoschemas = getEmployeeDetailResponseDtoSchemaRepository().findByCriteria(criteria); + return mapPaginatedEntityList(employeedetailresponsedtoschemas, EmployeeDetailResponseDtoSchemaEto.class); + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeInsertRequestDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeInsertRequestDtoSchemaImpl.java new file mode 100644 index 0000000..cb46a49 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeInsertRequestDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeInsertRequestDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcFindEmployeeInsertRequestDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeInsertRequestDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeInsertRequestDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeInsertRequestDtoSchemaSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting EmployeeInsertRequestDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcFindEmployeeInsertRequestDtoSchemaImpl extends AbstractEmployeeInsertRequestDtoSchemaUc implements UcFindEmployeeInsertRequestDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindEmployeeInsertRequestDtoSchemaImpl.class); + + + @Override + public EmployeeInsertRequestDtoSchemaEto findEmployeeInsertRequestDtoSchema(long id) { + LOG.debug("Get EmployeeInsertRequestDtoSchema with id {} from database.", id); + Optional foundEntity = getEmployeeInsertRequestDtoSchemaRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), EmployeeInsertRequestDtoSchemaEto.class); + else + return null; + } + + @Override + public Page findEmployeeInsertRequestDtoSchemas(EmployeeInsertRequestDtoSchemaSearchCriteriaTo criteria) { + Page employeeinsertrequestdtoschemas = getEmployeeInsertRequestDtoSchemaRepository().findByCriteria(criteria); + return mapPaginatedEntityList(employeeinsertrequestdtoschemas, EmployeeInsertRequestDtoSchemaEto.class); + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeInsertResponseDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeInsertResponseDtoSchemaImpl.java new file mode 100644 index 0000000..6f9da51 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeInsertResponseDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeInsertResponseDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcFindEmployeeInsertResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeInsertResponseDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeInsertResponseDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeInsertResponseDtoSchemaSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting EmployeeInsertResponseDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcFindEmployeeInsertResponseDtoSchemaImpl extends AbstractEmployeeInsertResponseDtoSchemaUc implements UcFindEmployeeInsertResponseDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindEmployeeInsertResponseDtoSchemaImpl.class); + + + @Override + public EmployeeInsertResponseDtoSchemaEto findEmployeeInsertResponseDtoSchema(long id) { + LOG.debug("Get EmployeeInsertResponseDtoSchema with id {} from database.", id); + Optional foundEntity = getEmployeeInsertResponseDtoSchemaRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), EmployeeInsertResponseDtoSchemaEto.class); + else + return null; + } + + @Override + public Page findEmployeeInsertResponseDtoSchemas(EmployeeInsertResponseDtoSchemaSearchCriteriaTo criteria) { + Page employeeinsertresponsedtoschemas = getEmployeeInsertResponseDtoSchemaRepository().findByCriteria(criteria); + return mapPaginatedEntityList(employeeinsertresponsedtoschemas, EmployeeInsertResponseDtoSchemaEto.class); + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListContentResponseDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListContentResponseDtoSchemaImpl.java new file mode 100644 index 0000000..abdd922 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListContentResponseDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListContentResponseDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcFindEmployeeListContentResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeListContentResponseDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListContentResponseDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListContentResponseDtoSchemaSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting EmployeeListContentResponseDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcFindEmployeeListContentResponseDtoSchemaImpl extends AbstractEmployeeListContentResponseDtoSchemaUc implements UcFindEmployeeListContentResponseDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindEmployeeListContentResponseDtoSchemaImpl.class); + + + @Override + public EmployeeListContentResponseDtoSchemaEto findEmployeeListContentResponseDtoSchema(long id) { + LOG.debug("Get EmployeeListContentResponseDtoSchema with id {} from database.", id); + Optional foundEntity = getEmployeeListContentResponseDtoSchemaRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), EmployeeListContentResponseDtoSchemaEto.class); + else + return null; + } + + @Override + public Page findEmployeeListContentResponseDtoSchemas(EmployeeListContentResponseDtoSchemaSearchCriteriaTo criteria) { + Page employeelistcontentresponsedtoschemas = getEmployeeListContentResponseDtoSchemaRepository().findByCriteria(criteria); + return mapPaginatedEntityList(employeelistcontentresponsedtoschemas, EmployeeListContentResponseDtoSchemaEto.class); + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListRequestDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListRequestDtoSchemaImpl.java new file mode 100644 index 0000000..52639ed --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListRequestDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListRequestDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcFindEmployeeListRequestDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeListRequestDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListRequestDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListRequestDtoSchemaSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting EmployeeListRequestDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcFindEmployeeListRequestDtoSchemaImpl extends AbstractEmployeeListRequestDtoSchemaUc implements UcFindEmployeeListRequestDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindEmployeeListRequestDtoSchemaImpl.class); + + + @Override + public EmployeeListRequestDtoSchemaEto findEmployeeListRequestDtoSchema(long id) { + LOG.debug("Get EmployeeListRequestDtoSchema with id {} from database.", id); + Optional foundEntity = getEmployeeListRequestDtoSchemaRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), EmployeeListRequestDtoSchemaEto.class); + else + return null; + } + + @Override + public Page findEmployeeListRequestDtoSchemas(EmployeeListRequestDtoSchemaSearchCriteriaTo criteria) { + Page employeelistrequestdtoschemas = getEmployeeListRequestDtoSchemaRepository().findByCriteria(criteria); + return mapPaginatedEntityList(employeelistrequestdtoschemas, EmployeeListRequestDtoSchemaEto.class); + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListResponseDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListResponseDtoSchemaImpl.java new file mode 100644 index 0000000..2df0f13 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindEmployeeListResponseDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListResponseDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcFindEmployeeListResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeListResponseDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListResponseDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListResponseDtoSchemaSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting EmployeeListResponseDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcFindEmployeeListResponseDtoSchemaImpl extends AbstractEmployeeListResponseDtoSchemaUc implements UcFindEmployeeListResponseDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindEmployeeListResponseDtoSchemaImpl.class); + + + @Override + public EmployeeListResponseDtoSchemaEto findEmployeeListResponseDtoSchema(long id) { + LOG.debug("Get EmployeeListResponseDtoSchema with id {} from database.", id); + Optional foundEntity = getEmployeeListResponseDtoSchemaRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), EmployeeListResponseDtoSchemaEto.class); + else + return null; + } + + @Override + public Page findEmployeeListResponseDtoSchemas(EmployeeListResponseDtoSchemaSearchCriteriaTo criteria) { + Page employeelistresponsedtoschemas = getEmployeeListResponseDtoSchemaRepository().findByCriteria(criteria); + return mapPaginatedEntityList(employeelistresponsedtoschemas, EmployeeListResponseDtoSchemaEto.class); + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindPageableDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindPageableDtoSchemaImpl.java new file mode 100644 index 0000000..cf20c4b --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindPageableDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.PageableDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcFindPageableDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractPageableDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.PageableDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.PageableDtoSchemaSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting PageableDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcFindPageableDtoSchemaImpl extends AbstractPageableDtoSchemaUc implements UcFindPageableDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindPageableDtoSchemaImpl.class); + + + @Override + public PageableDtoSchemaEto findPageableDtoSchema(long id) { + LOG.debug("Get PageableDtoSchema with id {} from database.", id); + Optional foundEntity = getPageableDtoSchemaRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), PageableDtoSchemaEto.class); + else + return null; + } + + @Override + public Page findPageableDtoSchemas(PageableDtoSchemaSearchCriteriaTo criteria) { + Page pageabledtoschemas = getPageableDtoSchemaRepository().findByCriteria(criteria); + return mapPaginatedEntityList(pageabledtoschemas, PageableDtoSchemaEto.class); + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindPageableSortDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindPageableSortDtoSchemaImpl.java new file mode 100644 index 0000000..f10beaf --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcFindPageableSortDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.PageableSortDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcFindPageableSortDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractPageableSortDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.PageableSortDtoSchemaEntity; +import com.example.domain.myapp.employeemanagement.logic.api.to.PageableSortDtoSchemaSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting PageableSortDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcFindPageableSortDtoSchemaImpl extends AbstractPageableSortDtoSchemaUc implements UcFindPageableSortDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindPageableSortDtoSchemaImpl.class); + + + @Override + public PageableSortDtoSchemaEto findPageableSortDtoSchema(long id) { + LOG.debug("Get PageableSortDtoSchema with id {} from database.", id); + Optional foundEntity = getPageableSortDtoSchemaRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), PageableSortDtoSchemaEto.class); + else + return null; + } + + @Override + public Page findPageableSortDtoSchemas(PageableSortDtoSchemaSearchCriteriaTo criteria) { + Page pageablesortdtoschemas = getPageableSortDtoSchemaRepository().findByCriteria(criteria); + return mapPaginatedEntityList(pageablesortdtoschemas, PageableSortDtoSchemaEto.class); + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeDetailResponseDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeDetailResponseDtoSchemaImpl.java new file mode 100644 index 0000000..771b0ac --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeDetailResponseDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeDetailResponseDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcManageEmployeeDetailResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeDetailResponseDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeDetailResponseDtoSchemaEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting EmployeeDetailResponseDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcManageEmployeeDetailResponseDtoSchemaImpl extends AbstractEmployeeDetailResponseDtoSchemaUc implements UcManageEmployeeDetailResponseDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManageEmployeeDetailResponseDtoSchemaImpl.class); + + @Override + public boolean deleteEmployeeDetailResponseDtoSchema(long employeeDetailResponseDtoSchemaId) { + + EmployeeDetailResponseDtoSchemaEntity employeeDetailResponseDtoSchema = getEmployeeDetailResponseDtoSchemaRepository().find(employeeDetailResponseDtoSchemaId); + getEmployeeDetailResponseDtoSchemaRepository().delete(employeeDetailResponseDtoSchema); + LOG.debug("The employeeDetailResponseDtoSchema with id '{}' has been deleted.", employeeDetailResponseDtoSchemaId); + return true; + } + + @Override + public EmployeeDetailResponseDtoSchemaEto saveEmployeeDetailResponseDtoSchema(EmployeeDetailResponseDtoSchemaEto employeeDetailResponseDtoSchema) { + + Objects.requireNonNull(employeeDetailResponseDtoSchema, "employeeDetailResponseDtoSchema"); + + EmployeeDetailResponseDtoSchemaEntity employeeDetailResponseDtoSchemaEntity = getBeanMapper().map(employeeDetailResponseDtoSchema, EmployeeDetailResponseDtoSchemaEntity.class); + + //initialize, validate employeeDetailResponseDtoSchemaEntity here if necessary + EmployeeDetailResponseDtoSchemaEntity resultEntity = getEmployeeDetailResponseDtoSchemaRepository().save(employeeDetailResponseDtoSchemaEntity); + LOG.debug("EmployeeDetailResponseDtoSchema with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, EmployeeDetailResponseDtoSchemaEto.class); + } +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeInsertRequestDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeInsertRequestDtoSchemaImpl.java new file mode 100644 index 0000000..bb89c72 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeInsertRequestDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeInsertRequestDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcManageEmployeeInsertRequestDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeInsertRequestDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeInsertRequestDtoSchemaEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting EmployeeInsertRequestDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcManageEmployeeInsertRequestDtoSchemaImpl extends AbstractEmployeeInsertRequestDtoSchemaUc implements UcManageEmployeeInsertRequestDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManageEmployeeInsertRequestDtoSchemaImpl.class); + + @Override + public boolean deleteEmployeeInsertRequestDtoSchema(long employeeInsertRequestDtoSchemaId) { + + EmployeeInsertRequestDtoSchemaEntity employeeInsertRequestDtoSchema = getEmployeeInsertRequestDtoSchemaRepository().find(employeeInsertRequestDtoSchemaId); + getEmployeeInsertRequestDtoSchemaRepository().delete(employeeInsertRequestDtoSchema); + LOG.debug("The employeeInsertRequestDtoSchema with id '{}' has been deleted.", employeeInsertRequestDtoSchemaId); + return true; + } + + @Override + public EmployeeInsertRequestDtoSchemaEto saveEmployeeInsertRequestDtoSchema(EmployeeInsertRequestDtoSchemaEto employeeInsertRequestDtoSchema) { + + Objects.requireNonNull(employeeInsertRequestDtoSchema, "employeeInsertRequestDtoSchema"); + + EmployeeInsertRequestDtoSchemaEntity employeeInsertRequestDtoSchemaEntity = getBeanMapper().map(employeeInsertRequestDtoSchema, EmployeeInsertRequestDtoSchemaEntity.class); + + //initialize, validate employeeInsertRequestDtoSchemaEntity here if necessary + EmployeeInsertRequestDtoSchemaEntity resultEntity = getEmployeeInsertRequestDtoSchemaRepository().save(employeeInsertRequestDtoSchemaEntity); + LOG.debug("EmployeeInsertRequestDtoSchema with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, EmployeeInsertRequestDtoSchemaEto.class); + } +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeInsertResponseDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeInsertResponseDtoSchemaImpl.java new file mode 100644 index 0000000..fa78eb9 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeInsertResponseDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeInsertResponseDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcManageEmployeeInsertResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeInsertResponseDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeInsertResponseDtoSchemaEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting EmployeeInsertResponseDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcManageEmployeeInsertResponseDtoSchemaImpl extends AbstractEmployeeInsertResponseDtoSchemaUc implements UcManageEmployeeInsertResponseDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManageEmployeeInsertResponseDtoSchemaImpl.class); + + @Override + public boolean deleteEmployeeInsertResponseDtoSchema(long employeeInsertResponseDtoSchemaId) { + + EmployeeInsertResponseDtoSchemaEntity employeeInsertResponseDtoSchema = getEmployeeInsertResponseDtoSchemaRepository().find(employeeInsertResponseDtoSchemaId); + getEmployeeInsertResponseDtoSchemaRepository().delete(employeeInsertResponseDtoSchema); + LOG.debug("The employeeInsertResponseDtoSchema with id '{}' has been deleted.", employeeInsertResponseDtoSchemaId); + return true; + } + + @Override + public EmployeeInsertResponseDtoSchemaEto saveEmployeeInsertResponseDtoSchema(EmployeeInsertResponseDtoSchemaEto employeeInsertResponseDtoSchema) { + + Objects.requireNonNull(employeeInsertResponseDtoSchema, "employeeInsertResponseDtoSchema"); + + EmployeeInsertResponseDtoSchemaEntity employeeInsertResponseDtoSchemaEntity = getBeanMapper().map(employeeInsertResponseDtoSchema, EmployeeInsertResponseDtoSchemaEntity.class); + + //initialize, validate employeeInsertResponseDtoSchemaEntity here if necessary + EmployeeInsertResponseDtoSchemaEntity resultEntity = getEmployeeInsertResponseDtoSchemaRepository().save(employeeInsertResponseDtoSchemaEntity); + LOG.debug("EmployeeInsertResponseDtoSchema with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, EmployeeInsertResponseDtoSchemaEto.class); + } +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListContentResponseDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListContentResponseDtoSchemaImpl.java new file mode 100644 index 0000000..b50dc86 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListContentResponseDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListContentResponseDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcManageEmployeeListContentResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeListContentResponseDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListContentResponseDtoSchemaEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting EmployeeListContentResponseDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcManageEmployeeListContentResponseDtoSchemaImpl extends AbstractEmployeeListContentResponseDtoSchemaUc implements UcManageEmployeeListContentResponseDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManageEmployeeListContentResponseDtoSchemaImpl.class); + + @Override + public boolean deleteEmployeeListContentResponseDtoSchema(long employeeListContentResponseDtoSchemaId) { + + EmployeeListContentResponseDtoSchemaEntity employeeListContentResponseDtoSchema = getEmployeeListContentResponseDtoSchemaRepository().find(employeeListContentResponseDtoSchemaId); + getEmployeeListContentResponseDtoSchemaRepository().delete(employeeListContentResponseDtoSchema); + LOG.debug("The employeeListContentResponseDtoSchema with id '{}' has been deleted.", employeeListContentResponseDtoSchemaId); + return true; + } + + @Override + public EmployeeListContentResponseDtoSchemaEto saveEmployeeListContentResponseDtoSchema(EmployeeListContentResponseDtoSchemaEto employeeListContentResponseDtoSchema) { + + Objects.requireNonNull(employeeListContentResponseDtoSchema, "employeeListContentResponseDtoSchema"); + + EmployeeListContentResponseDtoSchemaEntity employeeListContentResponseDtoSchemaEntity = getBeanMapper().map(employeeListContentResponseDtoSchema, EmployeeListContentResponseDtoSchemaEntity.class); + + //initialize, validate employeeListContentResponseDtoSchemaEntity here if necessary + EmployeeListContentResponseDtoSchemaEntity resultEntity = getEmployeeListContentResponseDtoSchemaRepository().save(employeeListContentResponseDtoSchemaEntity); + LOG.debug("EmployeeListContentResponseDtoSchema with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, EmployeeListContentResponseDtoSchemaEto.class); + } +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListRequestDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListRequestDtoSchemaImpl.java new file mode 100644 index 0000000..7ace9f0 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListRequestDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListRequestDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcManageEmployeeListRequestDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeListRequestDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListRequestDtoSchemaEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting EmployeeListRequestDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcManageEmployeeListRequestDtoSchemaImpl extends AbstractEmployeeListRequestDtoSchemaUc implements UcManageEmployeeListRequestDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManageEmployeeListRequestDtoSchemaImpl.class); + + @Override + public boolean deleteEmployeeListRequestDtoSchema(long employeeListRequestDtoSchemaId) { + + EmployeeListRequestDtoSchemaEntity employeeListRequestDtoSchema = getEmployeeListRequestDtoSchemaRepository().find(employeeListRequestDtoSchemaId); + getEmployeeListRequestDtoSchemaRepository().delete(employeeListRequestDtoSchema); + LOG.debug("The employeeListRequestDtoSchema with id '{}' has been deleted.", employeeListRequestDtoSchemaId); + return true; + } + + @Override + public EmployeeListRequestDtoSchemaEto saveEmployeeListRequestDtoSchema(EmployeeListRequestDtoSchemaEto employeeListRequestDtoSchema) { + + Objects.requireNonNull(employeeListRequestDtoSchema, "employeeListRequestDtoSchema"); + + EmployeeListRequestDtoSchemaEntity employeeListRequestDtoSchemaEntity = getBeanMapper().map(employeeListRequestDtoSchema, EmployeeListRequestDtoSchemaEntity.class); + + //initialize, validate employeeListRequestDtoSchemaEntity here if necessary + EmployeeListRequestDtoSchemaEntity resultEntity = getEmployeeListRequestDtoSchemaRepository().save(employeeListRequestDtoSchemaEntity); + LOG.debug("EmployeeListRequestDtoSchema with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, EmployeeListRequestDtoSchemaEto.class); + } +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListResponseDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListResponseDtoSchemaImpl.java new file mode 100644 index 0000000..1682cf2 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManageEmployeeListResponseDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.EmployeeListResponseDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcManageEmployeeListResponseDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractEmployeeListResponseDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.EmployeeListResponseDtoSchemaEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting EmployeeListResponseDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcManageEmployeeListResponseDtoSchemaImpl extends AbstractEmployeeListResponseDtoSchemaUc implements UcManageEmployeeListResponseDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManageEmployeeListResponseDtoSchemaImpl.class); + + @Override + public boolean deleteEmployeeListResponseDtoSchema(long employeeListResponseDtoSchemaId) { + + EmployeeListResponseDtoSchemaEntity employeeListResponseDtoSchema = getEmployeeListResponseDtoSchemaRepository().find(employeeListResponseDtoSchemaId); + getEmployeeListResponseDtoSchemaRepository().delete(employeeListResponseDtoSchema); + LOG.debug("The employeeListResponseDtoSchema with id '{}' has been deleted.", employeeListResponseDtoSchemaId); + return true; + } + + @Override + public EmployeeListResponseDtoSchemaEto saveEmployeeListResponseDtoSchema(EmployeeListResponseDtoSchemaEto employeeListResponseDtoSchema) { + + Objects.requireNonNull(employeeListResponseDtoSchema, "employeeListResponseDtoSchema"); + + EmployeeListResponseDtoSchemaEntity employeeListResponseDtoSchemaEntity = getBeanMapper().map(employeeListResponseDtoSchema, EmployeeListResponseDtoSchemaEntity.class); + + //initialize, validate employeeListResponseDtoSchemaEntity here if necessary + EmployeeListResponseDtoSchemaEntity resultEntity = getEmployeeListResponseDtoSchemaRepository().save(employeeListResponseDtoSchemaEntity); + LOG.debug("EmployeeListResponseDtoSchema with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, EmployeeListResponseDtoSchemaEto.class); + } +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManagePageableDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManagePageableDtoSchemaImpl.java new file mode 100644 index 0000000..2c72da5 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManagePageableDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.PageableDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcManagePageableDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractPageableDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.PageableDtoSchemaEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting PageableDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcManagePageableDtoSchemaImpl extends AbstractPageableDtoSchemaUc implements UcManagePageableDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManagePageableDtoSchemaImpl.class); + + @Override + public boolean deletePageableDtoSchema(long pageableDtoSchemaId) { + + PageableDtoSchemaEntity pageableDtoSchema = getPageableDtoSchemaRepository().find(pageableDtoSchemaId); + getPageableDtoSchemaRepository().delete(pageableDtoSchema); + LOG.debug("The pageableDtoSchema with id '{}' has been deleted.", pageableDtoSchemaId); + return true; + } + + @Override + public PageableDtoSchemaEto savePageableDtoSchema(PageableDtoSchemaEto pageableDtoSchema) { + + Objects.requireNonNull(pageableDtoSchema, "pageableDtoSchema"); + + PageableDtoSchemaEntity pageableDtoSchemaEntity = getBeanMapper().map(pageableDtoSchema, PageableDtoSchemaEntity.class); + + //initialize, validate pageableDtoSchemaEntity here if necessary + PageableDtoSchemaEntity resultEntity = getPageableDtoSchemaRepository().save(pageableDtoSchemaEntity); + LOG.debug("PageableDtoSchema with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, PageableDtoSchemaEto.class); + } +} diff --git a/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManagePageableSortDtoSchemaImpl.java b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManagePageableSortDtoSchemaImpl.java new file mode 100644 index 0000000..28bd301 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/employeemanagement/logic/impl/usecase/UcManagePageableSortDtoSchemaImpl.java @@ -0,0 +1,49 @@ +package com.example.domain.myapp.employeemanagement.logic.impl.usecase; + +import com.example.domain.myapp.employeemanagement.logic.api.to.PageableSortDtoSchemaEto; +import com.example.domain.myapp.employeemanagement.logic.api.usecase.UcManagePageableSortDtoSchema; +import com.example.domain.myapp.employeemanagement.logic.base.usecase.AbstractPageableSortDtoSchemaUc; +import com.example.domain.myapp.employeemanagement.dataaccess.api.PageableSortDtoSchemaEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting PageableSortDtoSchemas + */ +@Named +@Validated +@Transactional +public class UcManagePageableSortDtoSchemaImpl extends AbstractPageableSortDtoSchemaUc implements UcManagePageableSortDtoSchema { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManagePageableSortDtoSchemaImpl.class); + + @Override + public boolean deletePageableSortDtoSchema(long pageableSortDtoSchemaId) { + + PageableSortDtoSchemaEntity pageableSortDtoSchema = getPageableSortDtoSchemaRepository().find(pageableSortDtoSchemaId); + getPageableSortDtoSchemaRepository().delete(pageableSortDtoSchema); + LOG.debug("The pageableSortDtoSchema with id '{}' has been deleted.", pageableSortDtoSchemaId); + return true; + } + + @Override + public PageableSortDtoSchemaEto savePageableSortDtoSchema(PageableSortDtoSchemaEto pageableSortDtoSchema) { + + Objects.requireNonNull(pageableSortDtoSchema, "pageableSortDtoSchema"); + + PageableSortDtoSchemaEntity pageableSortDtoSchemaEntity = getBeanMapper().map(pageableSortDtoSchema, PageableSortDtoSchemaEntity.class); + + //initialize, validate pageableSortDtoSchemaEntity here if necessary + PageableSortDtoSchemaEntity resultEntity = getPageableSortDtoSchemaRepository().save(pageableSortDtoSchemaEntity); + LOG.debug("PageableSortDtoSchema with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, PageableSortDtoSchemaEto.class); + } +} diff --git a/myapp/src/main/java/com/example/domain/myapp/general/common/base/AbstractBeanMapperSupport.java b/myapp/src/main/java/com/example/domain/myapp/general/common/base/AbstractBeanMapperSupport.java new file mode 100644 index 0000000..1945c53 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/general/common/base/AbstractBeanMapperSupport.java @@ -0,0 +1,24 @@ +package com.example.domain.myapp.general.common.base; + +import com.devonfw.module.beanmapping.common.api.BeanMapper; + +import javax.inject.Inject; + +/** + * This abstract class wraps advanced functionality according dozer mappings + */ +public abstract class AbstractBeanMapperSupport { + + /** @see #getBeanMapper() */ + @Inject + private BeanMapper beanMapper; + + /** + * @return the {@link BeanMapper} instance. + */ + protected BeanMapper getBeanMapper() { + + return this.beanMapper; + } + +} diff --git a/myapp/src/main/java/com/example/domain/myapp/general/logic/base/AbstractLogic.java b/myapp/src/main/java/com/example/domain/myapp/general/logic/base/AbstractLogic.java new file mode 100644 index 0000000..ec94488 --- /dev/null +++ b/myapp/src/main/java/com/example/domain/myapp/general/logic/base/AbstractLogic.java @@ -0,0 +1,86 @@ +package com.example.domain.myapp.general.logic.base; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import com.devonfw.module.basic.common.api.entity.GenericEntity; +import com.devonfw.module.basic.common.api.entity.PersistenceEntity; +import com.example.domain.myapp.general.common.base.AbstractBeanMapperSupport; + +/** + * Common code utilities for both AbstractUc and AbstractComponentFacade + */ +public class AbstractLogic extends AbstractBeanMapperSupport { + + /** + * Maps a {@link Page paginated list} of persistent entities to a {@link Page paginated list} of + * transfer objects. + * + * @param is the generic type of the {@link AbstractTransferObject transfer object}. + * @param is the generic type of the {@link PersistenceEntity entity}. + * @param page is the paginated list to map from. + * @param clazz is the target class to map the paginated entities to. + * @return a {@link Page paginated list of entity transfer objects}. + */ + protected > Page mapPaginatedEntityList(Page page, Class clazz) { + + List etoList = getBeanMapper().mapList(page.getContent(), clazz); + return new PageImpl<>(etoList, page.getPageable(), page.getTotalElements()); + } + + /** + * Creates a {@link Map} with all {@link GenericEntity entities} from the given {@link Collection} using their + * {@link GenericEntity#getId() ID} as key. All {@link GenericEntity entities} without an {@link GenericEntity#getId() + * ID} ({@code null}) will be ignored. + * + * @param is the generic type of the {@link GenericEntity#getId() ID}. + * @param is the generic type of the {@link GenericEntity entity}. + * @param entities is the {@link Collection} of {@link GenericEntity entities}. + * @return a {@link Map} mapping from {@link GenericEntity#getId() ID} to {@link GenericEntity entity}. + */ + protected static > Map getEntityMap(Collection entities) { + + Map id2EntityMap = new HashMap<>(); + for (E entity : entities) { + ID id = entity.getId(); + if (id != null) { + id2EntityMap.put(id, entity); + } + } + return id2EntityMap; + } + + /** + * Determines the {@link GenericEntity entities} to delete if currentList is the current list from the + * persistence and listToSave is the new list that shall be saved. In other words this method selects the + * {@link GenericEntity entities} from currentList that are not contained in listToSave. + * + * @param is the generic type of the {@link GenericEntity#getId() ID}. + * @param is the generic type of the {@link GenericEntity entity}. + * @param currentEntities is the {@link Collection} of the {@link GenericEntity entities} currently persisted. We +assume that all objects in this list have an {@link GenericEntity#getId() ID} value (that is not +{@code null}). + * @param entitiesToSave is the {@link Collection} that contains the {@link GenericEntity entities} that shall be +saved. It may contain {@link GenericEntity entities} that have no {@link GenericEntity#getId() ID} that +shall be newly created. + * @return the {@link List} with the {@link GenericEntity entities} to delete. + */ + protected static > List getEntities2Delete(Collection currentEntities, Collection entitiesToSave) { + + List result = new ArrayList<>(currentEntities.size()); + Map entityMap = getEntityMap(entitiesToSave); + for (E entity : currentEntities) { + if (!entityMap.containsKey(entity.getId())) { + // entity from currentList is not contained in listToSave... + result.add(entity); + } + } + return result; + } + +} diff --git a/myapp/src/main/java/com/flutter/counter/dataaccess/api/CounterEntity.java b/myapp/src/main/java/com/flutter/counter/dataaccess/api/CounterEntity.java new file mode 100644 index 0000000..a8ae143 --- /dev/null +++ b/myapp/src/main/java/com/flutter/counter/dataaccess/api/CounterEntity.java @@ -0,0 +1,37 @@ +package com.flutter.counter.dataaccess.api; + +import com.flutter.counter.common.api.Counter; +import com.flutter.general.dataaccess.api.ApplicationPersistenceEntity; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Transient; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotNull; + +import java.math.BigDecimal; + + /** + * Data access object for Counter entities + */ +@Entity +@javax.persistence.Table(name = "Counter") +public class CounterEntity extends ApplicationPersistenceEntity implements Counter { + + private static final long serialVersionUID = 1L; + + private BigInteger amount; + + public BigInteger getAmount() { + return this.amount; + } + + public void setAmount(BigInteger amount) { + this.amount = amount; + } + + +} diff --git a/myapp/src/main/java/com/flutter/counter/dataaccess/api/repo/CounterRepository.java b/myapp/src/main/java/com/flutter/counter/dataaccess/api/repo/CounterRepository.java new file mode 100644 index 0000000..fa6a5e8 --- /dev/null +++ b/myapp/src/main/java/com/flutter/counter/dataaccess/api/repo/CounterRepository.java @@ -0,0 +1,76 @@ +package com.flutter.counter.dataaccess.api.repo; + +import static com.querydsl.core.alias.Alias.$; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.querydsl.jpa.impl.JPAQuery; +import java.util.Iterator; + +import com.flutter.counter.common.api.Counter; +import com.flutter.counter.dataaccess.api.CounterEntity; +import com.flutter.counter.logic.api.to.CounterSearchCriteriaTo; +import com.devonfw.module.jpa.dataaccess.api.QueryUtil; +import com.devonfw.module.jpa.dataaccess.api.data.DefaultRepository; + +/** + * {@link DefaultRepository} for {@link CounterEntity} + */ +public interface CounterRepository extends DefaultRepository { + + /** + * @param criteria the {@link CounterSearchCriteriaTo} with the criteria to search. + * @return the {@link Page} of the {@link CounterEntity} objects that matched the search. + * If no pageable is set, it will return a unique page with all the objects that matched the search. + */ + default Page findByCriteria(CounterSearchCriteriaTo criteria) { + + CounterEntity alias = newDslAlias(); + JPAQuery query = newDslQuery(alias); + +BigInteger amount = criteria.getAmount(); +if (amount != null) { +query.where($(alias.getAmount()).eq(amount)); +} if (criteria.getPageable() == null) { + criteria.setPageable(PageRequest.of(0, Integer.MAX_VALUE)); + } else { + addOrderBy(query, alias, criteria.getPageable().getSort()); + } + + return QueryUtil.get().findPaginated(criteria.getPageable(), query, true); + } + + /** + * Add sorting to the given query on the given alias + * + * @param query to add sorting to + * @param alias to retrieve columns from for sorting + * @param sort specification of sorting + */ + public default void addOrderBy(JPAQuery query, CounterEntity alias, Sort sort) { + if (sort != null && sort.isSorted()) { + Iterator it = sort.iterator(); + while (it.hasNext()) { + Order next = it.next(); + switch(next.getProperty()) { + case "amount": + if (next.isAscending()) { + query.orderBy($(alias.getAmount()).asc()); + } else { + query.orderBy($(alias.getAmount()).desc()); + } + break; + default: + throw new IllegalArgumentException("Sorted by the unknown property '"+next.getProperty()+"'"); + } + } + } +} + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/flutter/counter/logic/base/usecase/AbstractCounterUc.java b/myapp/src/main/java/com/flutter/counter/logic/base/usecase/AbstractCounterUc.java new file mode 100644 index 0000000..bf6989a --- /dev/null +++ b/myapp/src/main/java/com/flutter/counter/logic/base/usecase/AbstractCounterUc.java @@ -0,0 +1,26 @@ +package com.flutter.counter.logic.base.usecase; + +import com.flutter.general.logic.base.AbstractUc; +import com.flutter.counter.dataaccess.api.repo.CounterRepository; + +import javax.inject.Inject; + +/** + * Abstract use case for Counters, which provides access to the commonly necessary data access objects. + */ +public class AbstractCounterUc extends AbstractUc { + + /** @see #getCounterRepository() */ + @Inject + private CounterRepository counterRepository; + + /** + * Returns the field 'counterRepository'. + * @return the {@link CounterRepository} instance. + */ + public CounterRepository getCounterRepository() { + + return this.counterRepository; + } + +} diff --git a/myapp/src/main/java/com/flutter/counter/logic/impl/CounterImpl.java b/myapp/src/main/java/com/flutter/counter/logic/impl/CounterImpl.java new file mode 100644 index 0000000..0d437ef --- /dev/null +++ b/myapp/src/main/java/com/flutter/counter/logic/impl/CounterImpl.java @@ -0,0 +1,74 @@ +package com.flutter.counter.logic.impl; + +import com.flutter.general.logic.base.AbstractComponentFacade; +import com.flutter.counter.logic.api.Counter; +import com.flutter.counter.logic.api.to.CounterEto; +import com.flutter.counter.logic.api.usecase.UcFindCounter; +import com.flutter.counter.logic.api.usecase.UcManageCounter; +import com.flutter.counter.logic.api.to.CounterSearchCriteriaTo; +import org.springframework.data.domain.Page; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; + +/** + * Implementation of component interface of counter + */ +@Named +public class CounterImpl extends AbstractComponentFacade implements Counter { + + @Inject + private UcFindCounter ucFindCounter; + + @Inject + private UcManageCounter ucManageCounter; + + @Override + public CounterEto findCounter(long id) { + + return this.ucFindCounter.findCounter(id); + } + + @Override + public Page findCounters(CounterSearchCriteriaTo criteria) { + return this.ucFindCounter.findCounters(criteria); + } + + @Override + public CounterEto saveCounter(CounterEto counter) { + + return this.ucManageCounter.saveCounter(counter); + } + + @Override + public boolean deleteCounter(long id) { + + return this.ucManageCounter.deleteCounter(id); + } + + @Override + public void getCounter( +) + { +// TODO getCounter +} + + @Override + public void resetCounter( +) + { +// TODO resetCounter +} + + @Override + public void incCounter( + CounterEto counter + ) + { +// TODO incCounter +} + +} diff --git a/myapp/src/main/java/com/flutter/counter/logic/impl/usecase/UcFindCounterImpl.java b/myapp/src/main/java/com/flutter/counter/logic/impl/usecase/UcFindCounterImpl.java new file mode 100644 index 0000000..c65aa5b --- /dev/null +++ b/myapp/src/main/java/com/flutter/counter/logic/impl/usecase/UcFindCounterImpl.java @@ -0,0 +1,49 @@ +package com.flutter.counter.logic.impl.usecase; + +import com.flutter.counter.logic.api.to.CounterEto; +import com.flutter.counter.logic.api.usecase.UcFindCounter; +import com.flutter.counter.logic.base.usecase.AbstractCounterUc; +import com.flutter.counter.dataaccess.api.CounterEntity; +import com.flutter.counter.logic.api.to.CounterSearchCriteriaTo; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.validation.annotation.Validated; +import java.util.List; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for searching, filtering and getting Counters + */ +@Named +@Validated +@Transactional +public class UcFindCounterImpl extends AbstractCounterUc implements UcFindCounter { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcFindCounterImpl.class); + + + @Override + public CounterEto findCounter(long id) { + LOG.debug("Get Counter with id {} from database.", id); + Optional foundEntity = getCounterRepository().findById(id); + if (foundEntity.isPresent()) + return getBeanMapper().map(foundEntity.get(), CounterEto.class); + else + return null; + } + + @Override + public Page findCounters(CounterSearchCriteriaTo criteria) { + Page counters = getCounterRepository().findByCriteria(criteria); + return mapPaginatedEntityList(counters, CounterEto.class); + } + +} diff --git a/myapp/src/main/java/com/flutter/counter/logic/impl/usecase/UcManageCounterImpl.java b/myapp/src/main/java/com/flutter/counter/logic/impl/usecase/UcManageCounterImpl.java new file mode 100644 index 0000000..9666dc3 --- /dev/null +++ b/myapp/src/main/java/com/flutter/counter/logic/impl/usecase/UcManageCounterImpl.java @@ -0,0 +1,49 @@ +package com.flutter.counter.logic.impl.usecase; + +import com.flutter.counter.logic.api.to.CounterEto; +import com.flutter.counter.logic.api.usecase.UcManageCounter; +import com.flutter.counter.logic.base.usecase.AbstractCounterUc; +import com.flutter.counter.dataaccess.api.CounterEntity; +import org.springframework.validation.annotation.Validated; +import java.util.Objects; + +import javax.inject.Named; + +import org.springframework.transaction.annotation.Transactional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use case implementation for modifying and deleting Counters + */ +@Named +@Validated +@Transactional +public class UcManageCounterImpl extends AbstractCounterUc implements UcManageCounter { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UcManageCounterImpl.class); + + @Override + public boolean deleteCounter(long counterId) { + + CounterEntity counter = getCounterRepository().find(counterId); + getCounterRepository().delete(counter); + LOG.debug("The counter with id '{}' has been deleted.", counterId); + return true; + } + + @Override + public CounterEto saveCounter(CounterEto counter) { + + Objects.requireNonNull(counter, "counter"); + + CounterEntity counterEntity = getBeanMapper().map(counter, CounterEntity.class); + + //initialize, validate counterEntity here if necessary + CounterEntity resultEntity = getCounterRepository().save(counterEntity); + LOG.debug("Counter with id '{}' has been created.",resultEntity.getId()); + return getBeanMapper().map(resultEntity, CounterEto.class); + } +} diff --git a/myapp/src/main/java/com/flutter/counter/service/impl/rest/CounterRestServiceImpl.java b/myapp/src/main/java/com/flutter/counter/service/impl/rest/CounterRestServiceImpl.java new file mode 100644 index 0000000..bdeefd3 --- /dev/null +++ b/myapp/src/main/java/com/flutter/counter/service/impl/rest/CounterRestServiceImpl.java @@ -0,0 +1,73 @@ +package com.flutter.counter.service.impl.rest; + +import javax.inject.Inject; +import javax.inject.Named; + +import com.flutter.counter.logic.api.Counter; +import com.flutter.counter.logic.api.to.CounterEto; +import com.flutter.counter.logic.api.to.CounterSearchCriteriaTo; +import com.flutter.counter.service.api.rest.CounterRestService; + +import org.springframework.data.domain.Page; + +import java.math.BigDecimal; +import java.util.List; + +/** + * The service implementation for REST calls in order to execute the logic of component {@link Counter}. + */ +@Named("CounterRestService") +public class CounterRestServiceImpl implements CounterRestService { + + @Inject + private Counter counter; + + @Override + public CounterEto getCounter(long id) { + + return this.counter.findCounter(id); + } + + @Override + public CounterEto saveCounter(CounterEto counter) { + + return this.counter.saveCounter(counter); + } + + @Override + public void deleteCounter(long id) { + + this.counter.deleteCounter(id); + } + + @Override + public Page findCountersByPost(CounterSearchCriteriaTo searchCriteriaTo) { + + return this.counter.findCounters(searchCriteriaTo); + } + + @Override + public void getCounter( + ) { + + this.counter.getCounter( + ); + } + @Override + public void resetCounter( + ) { + + this.counter.resetCounter( + ); + } + @Override + public void incCounter( + CounterEto counter + ) { + + this.counter.incCounter( + counter + ); + } + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/flutter/general/common/api/ApplicationEntity.java b/myapp/src/main/java/com/flutter/general/common/api/ApplicationEntity.java new file mode 100644 index 0000000..e651db7 --- /dev/null +++ b/myapp/src/main/java/com/flutter/general/common/api/ApplicationEntity.java @@ -0,0 +1,11 @@ +package com.flutter.general.common.api; + +import com.devonfw.module.basic.common.api.entity.GenericEntity; + +/** + * This is the abstract interface for a {@link GenericEntity}. We are using {@link Long} for + * all {@link #getId() primary keys}. + */ +public abstract interface ApplicationEntity extends GenericEntity { + +} diff --git a/myapp/src/main/java/com/flutter/general/common/base/AbstractBeanMapperSupport.java b/myapp/src/main/java/com/flutter/general/common/base/AbstractBeanMapperSupport.java new file mode 100644 index 0000000..64d4957 --- /dev/null +++ b/myapp/src/main/java/com/flutter/general/common/base/AbstractBeanMapperSupport.java @@ -0,0 +1,24 @@ +package com.flutter.general.common.base; + +import com.devonfw.module.beanmapping.common.api.BeanMapper; + +import javax.inject.Inject; + +/** + * This abstract class wraps advanced functionality according dozer mappings + */ +public abstract class AbstractBeanMapperSupport { + + /** @see #getBeanMapper() */ + @Inject + private BeanMapper beanMapper; + + /** + * @return the {@link BeanMapper} instance. + */ + protected BeanMapper getBeanMapper() { + + return this.beanMapper; + } + +} diff --git a/myapp/src/main/java/com/flutter/general/dataaccess/api/ApplicationPersistenceEntity.java b/myapp/src/main/java/com/flutter/general/dataaccess/api/ApplicationPersistenceEntity.java new file mode 100644 index 0000000..a17f25e --- /dev/null +++ b/myapp/src/main/java/com/flutter/general/dataaccess/api/ApplicationPersistenceEntity.java @@ -0,0 +1,94 @@ +package com.flutter.general.dataaccess.api; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Transient; +import javax.persistence.Version; + +import com.flutter.general.common.api.ApplicationEntity; + +import com.devonfw.module.basic.common.api.entity.PersistenceEntity; + +/** + * Abstract Entity for all Entities with an id and a version field. + */ +@MappedSuperclass +public abstract class ApplicationPersistenceEntity implements ApplicationEntity, PersistenceEntity { + + private static final long serialVersionUID = 1L; + + /** @see #getId() */ + private Long id; + + /** @see #getModificationCounter() */ + private int modificationCounter; + + /** @see #getRevision() */ + private Number revision; + + + /** + * The constructor. + */ + public ApplicationPersistenceEntity() { + + super(); + } + + @Override + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getId() { + + return this.id; + } + + /** + * {@inheritDoc} + */ + @Override + public void setId(Long id) { + + this.id = id; + } + + @Override + @Version + public int getModificationCounter() { + + return this.modificationCounter; + } + + @Override + public void setModificationCounter(int version) { + + this.modificationCounter = version; + } + + @Override + public String toString() { + + StringBuilder buffer = new StringBuilder(); + toString(buffer); + return buffer.toString(); + } + + /** + * Method to extend {@link #toString()} logic. + * + * @param buffer is the {@link StringBuilder} where to {@link StringBuilder#append(Object) append} the string + * representation. + */ + protected void toString(StringBuilder buffer) { + + buffer.append(getClass().getSimpleName()); + if (this.id != null) { + buffer.append("[id="); + buffer.append(this.id); + buffer.append("]"); + } + } + +} diff --git a/myapp/src/main/java/com/flutter/general/logic/base/AbstractComponentFacade.java b/myapp/src/main/java/com/flutter/general/logic/base/AbstractComponentFacade.java new file mode 100644 index 0000000..e64f43a --- /dev/null +++ b/myapp/src/main/java/com/flutter/general/logic/base/AbstractComponentFacade.java @@ -0,0 +1,16 @@ +package com.flutter.general.logic.base; + +/** + * Abstract base class for any management implementation class in this application. + */ +public abstract class AbstractComponentFacade extends AbstractLogic { + +/** + * The constructor. + */ + public AbstractComponentFacade() { + + super(); + } + +} diff --git a/myapp/src/main/java/com/flutter/general/logic/base/AbstractLogic.java b/myapp/src/main/java/com/flutter/general/logic/base/AbstractLogic.java new file mode 100644 index 0000000..1d95d94 --- /dev/null +++ b/myapp/src/main/java/com/flutter/general/logic/base/AbstractLogic.java @@ -0,0 +1,91 @@ +package com.flutter.general.logic.base; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; + +import com.devonfw.module.basic.common.api.entity.GenericEntity; +import com.devonfw.module.basic.common.api.entity.PersistenceEntity; +import com.flutter.general.common.base.AbstractBeanMapperSupport; + +/** + * Common code utilities for both AbstractUc and AbstractComponentFacade + * + */ +public class AbstractLogic extends AbstractBeanMapperSupport { + + /** + * Maps a {@link Page paginated list} of persistent entities to a {@link Page paginated list} of + * transfer objects. + * + * @param is the generic type of the {@link AbstractTransferObject transfer object}. + * @param is the generic type of the {@link PersistenceEntity entity}. + * @param page is the paginated list to map from. + * @param clazz is the target class to map the paginated entities to. + * @return a {@link Page paginated list of entity transfer objects}. + */ + protected > Page mapPaginatedEntityList( + Page page, Class clazz) { + + List etoList = getBeanMapper().mapList(page.getContent(), clazz); + return new PageImpl<>(etoList, page.getPageable(), page.getTotalElements()); + } + + /** + * Creates a {@link Map} with all {@link GenericEntity entities} from the given {@link Collection} using their + * {@link GenericEntity#getId() ID} as key. All {@link GenericEntity entities} without an {@link GenericEntity#getId() + * ID} ({@code null}) will be ignored. + * + * @param is the generic type of the {@link GenericEntity#getId() ID}. + * @param is the generic type of the {@link GenericEntity entity}. + * @param entities is the {@link Collection} of {@link GenericEntity entities}. + * @return a {@link Map} mapping from {@link GenericEntity#getId() ID} to {@link GenericEntity entity}. + */ + protected static > Map getEntityMap(Collection entities) { + + Map id2EntityMap = new HashMap<>(); + for (E entity : entities) { + ID id = entity.getId(); + if (id != null) { + id2EntityMap.put(id, entity); + } + } + return id2EntityMap; + } + + /** + * Determines the {@link GenericEntity entities} to delete if currentList is the current list from the + * persistence and listToSave is the new list that shall be saved. In other words this method selects the + * {@link GenericEntity entities} from currentList that are not contained in listToSave. + * + * @param is the generic type of the {@link GenericEntity#getId() ID}. + * @param is the generic type of the {@link GenericEntity entity}. + * @param currentEntities is the {@link Collection} of the {@link GenericEntity entities} currently persisted. We + * assume that all objects in this list have an {@link GenericEntity#getId() ID} value (that is not + * {@code null}). + * @param entitiesToSave is the {@link Collection} that contains the {@link GenericEntity entities} that shall be + * saved. It may contain {@link GenericEntity entities} that have no {@link GenericEntity#getId() ID} that + * shall be newly created. + * @return the {@link List} with the {@link GenericEntity entities} to delete. + */ + protected static > List getEntities2Delete(Collection currentEntities, + Collection entitiesToSave) { + + List result = new ArrayList<>(currentEntities.size()); + Map entityMap = getEntityMap(entitiesToSave); + for (E entity : currentEntities) { + if (!entityMap.containsKey(entity.getId())) { + // entity from currentList is not contained in listToSave... + result.add(entity); + } + } + return result; + } + +} \ No newline at end of file diff --git a/myapp/src/main/java/com/flutter/general/logic/base/AbstractUc.java b/myapp/src/main/java/com/flutter/general/logic/base/AbstractUc.java new file mode 100644 index 0000000..2da6756 --- /dev/null +++ b/myapp/src/main/java/com/flutter/general/logic/base/AbstractUc.java @@ -0,0 +1,18 @@ +package com.flutter.general.logic.base; + +/** + * Abstract base class for any use case in this application. Actual implementations need to be annotated with + * {@link javax.inject.Named} and {@link com.flutter.general.logic.api.UseCase}. + * + */ +public class AbstractUc extends AbstractLogic { + + /** + * The constructor. + */ + public AbstractUc() { + + super(); + } + +} \ No newline at end of file